240 Commits

Author SHA1 Message Date
Julien Valverdé
db7608f7c3 Form work
Some checks failed
Lint / lint (push) Failing after 14s
2025-04-19 02:00:39 +02:00
Julien Valverdé
b78f99e808 Form work
All checks were successful
Lint / lint (push) Successful in 19s
2025-04-19 01:13:41 +02:00
Julien Valverdé
86dde2d286 Cleanup
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-18 23:57:55 +02:00
Julien Valverdé
596e0942c5 Form work
All checks were successful
Lint / lint (push) Successful in 15s
2025-04-18 23:52:58 +02:00
Julien Valverdé
cb61713cce Form work 2025-04-18 23:52:49 +02:00
Julien Valverdé
1b2b68fbae Form work
All checks were successful
Lint / lint (push) Successful in 15s
2025-04-17 04:59:43 +02:00
Julien Valverdé
35a8037f5a Form work 2025-04-17 02:30:23 +02:00
Julien Valverdé
7aef7ae796 Form work
All checks were successful
Lint / lint (push) Successful in 17s
2025-04-17 01:09:01 +02:00
Julien Valverdé
1bfbeba934 Form work
Some checks failed
Lint / lint (push) Failing after 14s
2025-04-16 04:35:22 +02:00
Julien Valverdé
fc4295894f Form work
Some checks failed
Lint / lint (push) Failing after 15s
2025-04-16 00:44:01 +02:00
Julien Valverdé
ab0dce107d Form work
Some checks failed
Lint / lint (push) Failing after 15s
2025-04-15 23:55:50 +02:00
Julien Valverdé
9436602443 Form work
All checks were successful
Lint / lint (push) Successful in 59s
2025-04-15 04:25:06 +02:00
Julien Valverdé
66de31706c Form work
Some checks failed
Lint / lint (push) Failing after 14s
2025-04-15 01:32:48 +02:00
Julien Valverdé
8925fe6336 Guards work
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-14 03:40:58 +02:00
Julien Valverdé
fe8ca23d37 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-14 02:55:33 +02:00
Julien Valverdé
d48f20a59d Schema guards
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-14 02:49:50 +02:00
Julien Valverdé
b7b4abcbe2 Merge branch 'next' into form
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-14 01:00:38 +02:00
Julien Valverdé
3497d17046 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-14 00:58:05 +02:00
Julien Valverdé
1ca832e69d Fix
All checks were successful
Lint / lint (push) Successful in 14s
Test build / test-build (pull_request) Successful in 21s
2025-04-14 00:54:06 +02:00
Julien Valverdé
98bd72d1d7 Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-13 18:29:00 +02:00
Julien Valverdé
f594f47793 VQueryErrorHandler
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-13 17:39:54 +02:00
Julien Valverdé
4f9827720c Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-13 17:18:06 +02:00
Julien Valverdé
0f761524fd Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-13 17:06:20 +02:00
Julien Valverdé
574136e161 SubscribeStream
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-13 03:21:11 +02:00
Julien Valverdé
7a12abdbdf useSubscribeStream
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-13 02:30:29 +02:00
Julien Valverdé
129ab04ea7 Form
All checks were successful
Lint / lint (push) Successful in 15s
2025-04-13 01:03:40 +02:00
Julien Valverdé
870fe479c3 Form package
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-13 00:23:40 +02:00
Julien Valverdé
8fecb94292 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-12 23:59:40 +02:00
Julien Valverdé
26a2111705 Version bump
All checks were successful
Lint / lint (push) Successful in 14s
Test build / test-build (pull_request) Successful in 43s
2025-04-12 23:52:35 +02:00
Julien Valverdé
1cb02407c8 Dependencies fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-12 23:47:43 +02:00
Julien Valverdé
6e8ce84851 Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-12 23:06:43 +02:00
Julien Valverdé
570fb93876 ReffuseHelpers -> ReffuseNamespace
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-12 23:03:17 +02:00
Julien Valverdé
821fd18f8f Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-12 18:30:37 +02:00
Julien Valverdé
b7ef95341b Tests
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-12 00:39:02 +02:00
Julien Valverdé
5f5ef5614b Working SubscribeRefs
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-12 00:16:04 +02:00
Julien Valverdé
cbd39f893e Done useSubscribeRefs
All checks were successful
Lint / lint (push) Successful in 16s
2025-04-11 23:40:06 +02:00
Julien Valverdé
529e3d3f9d useSubscribeRefs work
Some checks failed
Lint / lint (push) Failing after 10s
2025-04-11 21:43:32 +02:00
Julien Valverdé
9d47418a69 useRefsState work
Some checks failed
Lint / lint (push) Failing after 10s
2025-04-11 20:10:34 +02:00
Julien Valverdé
c1b6e73231 useRefsState work
All checks were successful
Lint / lint (push) Successful in 13s
2025-04-11 02:58:44 +02:00
Julien Valverdé
d1ba4148f2 useRefsState work
Some checks failed
Lint / lint (push) Failing after 11s
2025-04-11 02:10:21 +02:00
Julien Valverdé
ef13e87d12 Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-11 00:23:15 +02:00
Julien Valverdé
8b141b907f RefState tests
All checks were successful
Lint / lint (push) Successful in 14s
2025-04-10 23:06:13 +02:00
Julien Valverdé
52a36cb882 RefState component
All checks were successful
Lint / lint (push) Successful in 58s
2025-04-10 22:38:29 +02:00
Julien Valverdé
3b844f071b Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-31 21:43:29 +02:00
Julien Valverdé
4e422a1901 Version bump
All checks were successful
Lint / lint (push) Successful in 13s
Test build / test-build (pull_request) Successful in 17s
2025-03-31 21:40:55 +02:00
Julien Valverdé
a5c6b34dfe Example fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-31 21:19:41 +02:00
Julien Valverdé
ab1f851428 Refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-31 21:07:42 +02:00
Julien Valverdé
3f091d55c2 QueryClient refactoring
All checks were successful
Lint / lint (push) Successful in 17s
2025-03-31 20:54:32 +02:00
Julien Valverdé
76a33fccca Query refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-31 20:38:21 +02:00
Julien Valverdé
c75bb10e6b QueryClient work
Some checks failed
Lint / lint (push) Failing after 17s
2025-03-31 18:22:18 +02:00
Julien Valverdé
3da4b2a318 QueryClient work
Some checks failed
Lint / lint (push) Failing after 14s
2025-03-31 01:54:08 +02:00
Julien Valverdé
9a24ecaf84 QueryClient work
Some checks failed
Lint / lint (push) Failing after 14s
2025-03-31 00:00:47 +02:00
Julien Valverdé
7b20df6c71 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-28 21:26:06 +01:00
Julien Valverdé
f40dae90fb Version bump
All checks were successful
Lint / lint (push) Successful in 13s
Test build / test-build (pull_request) Successful in 44s
2025-03-28 21:22:32 +01:00
Julien Valverdé
46211638f5 Refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 21:19:17 +01:00
Julien Valverdé
a28d6c3d30 Refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 21:12:42 +01:00
Julien Valverdé
6b74b9a3b2 useMemoScoped refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 21:09:27 +01:00
Julien Valverdé
e17f945666 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 20:30:31 +01:00
Julien Valverdé
aa46ecc82d Async provider refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-28 20:27:25 +01:00
Julien Valverdé
8ea9146dd9 Provider refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 19:18:46 +01:00
Julien Valverdé
0a4bb2856d Provider refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-28 18:48:49 +01:00
Julien Valverdé
b4cd7daa81 Restore
Some checks failed
Lint / lint (push) Failing after 26s
2025-03-28 18:26:04 +01:00
Julien Valverdé
b5712d5433 Test
All checks were successful
Lint / lint (push) Successful in 36s
2025-03-28 17:39:23 +01:00
Julien Valverdé
57b7eac05c Test 2025-03-28 17:37:28 +01:00
Julien Valverdé
9a9bd78ec6 Provider work
Some checks failed
Lint / lint (push) Failing after 10s
2025-03-28 17:01:41 +01:00
Julien Valverdé
ddcd681ca4 Provider refactoring
Some checks failed
Lint / lint (push) Failing after 19m51s
2025-03-28 16:08:04 +01:00
Julien Valverdé
66de517ab5 Refactoring
Some checks failed
Lint / lint (push) Failing after 15m36s
2025-03-26 20:24:53 +01:00
Julien Valverdé
b50255ded2 Merge branch 'queryclient' of git.valverde.cloud:Thilawyn/reffuse into queryclient
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-26 19:34:59 +01:00
Julien Valverdé
03f0b623ed Removed JSX code 2025-03-26 19:34:21 +01:00
Julien Valverdé
fb6d803723 Removed JSX code 2025-03-26 19:34:14 +01:00
Julien Valverdé
972986241c ReffuseHelpers.make()
Some checks failed
Lint / lint (push) Has been cancelled
2025-03-25 19:29:17 +01:00
Julien Valverdé
9eb0904600 Refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 20:35:22 +01:00
Julien Valverdé
fc86c818e0 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 19:41:21 +01:00
Julien Valverdé
5a12139602 Regenerated lockfile
All checks were successful
Lint / lint (push) Successful in 13s
Test build / test-build (pull_request) Successful in 15s
2025-03-24 19:35:56 +01:00
Julien Valverdé
a0928c718f Version bump
All checks were successful
Lint / lint (push) Successful in 13s
Test build / test-build (pull_request) Successful in 15s
2025-03-24 19:33:35 +01:00
Julien Valverdé
49d9edd4b1 Dependencies upgrade
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-24 19:29:12 +01:00
Julien Valverdé
3552c25b5c Mutation refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 19:07:11 +01:00
Julien Valverdé
516e0a465d Ref state fix
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-24 18:38:14 +01:00
Julien Valverdé
7cf5367409 Tests
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-24 17:34:50 +01:00
Julien Valverdé
3b237c0588 Query refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 17:30:41 +01:00
Julien Valverdé
d9aa42d23a Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 12:16:03 +01:00
Julien Valverdé
fd3213c53f Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 12:06:03 +01:00
Julien Valverdé
baa8c92221 Query refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-24 12:03:55 +01:00
Julien Valverdé
d55b432846 Refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-23 23:58:05 +01:00
Julien Valverdé
6266c7506e Example fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-23 07:32:11 +01:00
Julien Valverdé
043e966e45 ErrorHandler work
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-23 07:25:03 +01:00
Julien Valverdé
88fab2c7d7 ErrorHandler refactoring
Some checks failed
Lint / lint (push) Failing after 15s
2025-03-23 06:08:35 +01:00
Julien Valverdé
224ccd8e32 Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 04:55:38 +01:00
Julien Valverdé
4cf70ada0b Fix
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-21 04:49:44 +01:00
Julien Valverdé
f9bd5d4d6b Query refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 04:37:32 +01:00
Julien Valverdé
1ec1db0658 Mutation progress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 03:38:48 +01:00
Julien Valverdé
2d94e84941 Stream fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 03:24:55 +01:00
Julien Valverdé
aab83907ba Working mutation progress
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 02:14:36 +01:00
Julien Valverdé
8c0d6b4c8a Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 01:24:52 +01:00
Julien Valverdé
d82d1d1c29 Refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 01:23:47 +01:00
Julien Valverdé
0f09573948 Mutation services
Some checks failed
Lint / lint (push) Failing after 14s
2025-03-20 07:10:55 +01:00
Julien Valverdé
2b6b36713e MutationRunner work
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-20 04:31:38 +01:00
Julien Valverdé
5d0aecc9d5 QueryProgress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-19 05:13:54 +01:00
Julien Valverdé
f21d8b2d8a QueryProgress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-18 03:11:39 +01:00
Julien Valverdé
f85173fa68 Fix
All checks were successful
Lint / lint (push) Successful in 30s
2025-03-18 02:46:41 +01:00
Julien Valverdé
65a124de1f Mutation tests
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-17 05:52:13 +01:00
Julien Valverdé
16893761c6 Mutation refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-17 05:34:19 +01:00
Julien Valverdé
3fdc2e31eb Mutation example
All checks were successful
Lint / lint (push) Successful in 17s
2025-03-17 02:36:13 +01:00
Julien Valverdé
8636a28f2f Working mutations
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-17 02:15:27 +01:00
Julien Valverdé
d56578da8f useMutation
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 06:50:20 +01:00
Julien Valverdé
299109d421 Mutation fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-16 06:25:02 +01:00
Julien Valverdé
4995b2949f MutationRunner
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 05:20:55 +01:00
Julien Valverdé
6e6e675709 MutationRunner 2025-03-16 05:20:37 +01:00
Julien Valverdé
b04860aa25 Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 04:32:51 +01:00
Julien Valverdé
e9e17ac211 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-16 04:11:25 +01:00
Julien Valverdé
1f0ff725ff Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 04:05:39 +01:00
Julien Valverdé
447d89982c Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:34:54 +01:00
Julien Valverdé
778ee27795 ErrorHandler refactoring
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-16 03:33:01 +01:00
Julien Valverdé
077816efb6 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:23:12 +01:00
Julien Valverdé
e4bacd1ca7 Working QueryClient refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:19:12 +01:00
Julien Valverdé
0e2c0db28f QueryClient refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 02:52:49 +01:00
Julien Valverdé
c943d81702 QueryClient.make
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-15 22:27:15 +01:00
Julien Valverdé
c2bc406a5f Fixed query error handler
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-15 06:43:47 +01:00
Julien Valverdé
4e778b6c95 VQueryErrorHandler
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-15 05:12:38 +01:00
Julien Valverdé
0437fa5dcc QueryErrorHandler work
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-15 02:30:37 +01:00
Julien Valverdé
5614b8df38 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-15 00:52:00 +01:00
Julien Valverdé
70b6c4434e Tests
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-14 22:07:53 +01:00
Julien Valverdé
2e8dfbc988 QueryClient
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-14 22:00:53 +01:00
Julien Valverdé
abc47c4647 Fix
Some checks failed
Lint / lint (push) Failing after 12s
2025-03-14 05:04:49 +01:00
Julien Valverdé
eedd2a7f2a makeTag
Some checks failed
Lint / lint (push) Failing after 12s
2025-03-14 04:57:07 +01:00
Julien Valverdé
f4ab575a8d QueryExtension work
Some checks failed
Lint / lint (push) Failing after 13s
2025-03-14 04:24:56 +01:00
Julien Valverdé
747e2c6056 Done QueryClient
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-14 04:13:14 +01:00
Julien Valverdé
68c68417d8 QueryClient work
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-14 03:56:54 +01:00
Julien Valverdé
ed384a62a8 QueryClient work
Some checks failed
Lint / lint (push) Failing after 15s
2025-03-14 03:26:28 +01:00
Julien Valverdé
3a1748bb39 QueryClient tests
All checks were successful
Lint / lint (push) Successful in 18s
2025-03-13 22:31:50 +01:00
Julien Valverdé
66b8fd2c2e Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-12 06:37:39 +01:00
Julien Valverdé
bc81c443ab Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 21:19:57 +01:00
Julien Valverdé
ee5dbe3766 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 20:39:56 +01:00
Julien Valverdé
825de84cef Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 03:12:36 +01:00
Julien Valverdé
d6011f7897 MutationRunner
Some checks failed
Lint / lint (push) Failing after 18s
2025-03-11 02:17:50 +01:00
Julien Valverdé
8d4bce9e53 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-11 01:45:49 +01:00
Julien Valverdé
f7dd4e51f5 Doc update
All checks were successful
Lint / lint (push) Successful in 13s
Test build / test-build (pull_request) Successful in 16s
2025-03-11 01:36:13 +01:00
Julien Valverdé
8772e25ff5 CI update
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-10 18:44:08 +01:00
Julien Valverdé
94a0864132 Query refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-10 18:37:45 +01:00
Julien Valverdé
be8098fb7d Query work
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-10 01:56:11 +01:00
Julien Valverdé
7021e604ed Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-09 19:14:20 +01:00
Julien Valverdé
1fd2a9ffbe Cleanup
All checks were successful
Lint / lint (push) Successful in 17s
2025-03-09 18:35:48 +01:00
Julien Valverdé
1ed73dc3ac Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-09 18:21:35 +01:00
Julien Valverdé
c689778cea Working query
All checks were successful
Lint / lint (push) Successful in 15s
2025-03-09 18:08:52 +01:00
Julien Valverdé
da2a32001c Query work
Some checks failed
Lint / lint (push) Failing after 13s
2025-03-08 01:56:50 +01:00
Julien Valverdé
5ac3a932d9 Query work
Some checks failed
Lint / lint (push) Failing after 12s
2025-03-07 23:17:32 +01:00
Julien Valverdé
7935293bc3 Query work
All checks were successful
Lint / lint (push) Successful in 15s
2025-03-07 22:23:44 +01:00
Julien Valverdé
cabceaffcd Key work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-07 04:26:39 +01:00
Julien Valverdé
d239a11cdc Service query
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-06 20:00:40 +01:00
Julien Valverdé
fad61afce7 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-06 17:32:30 +01:00
Julien Valverdé
11fd4941c0 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-06 17:26:08 +01:00
Julien Valverdé
7bebc39a87 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-06 17:22:27 +01:00
Julien Valverdé
3bc0cc6586 Cleanup
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-06 03:31:21 +01:00
Julien Valverdé
f99d18b846 Cleanup fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-06 03:15:43 +01:00
Julien Valverdé
d61339ea6a Query work
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-05 02:23:43 +01:00
Julien Valverdé
3659d3f342 Version bump
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-05 01:50:08 +01:00
Julien Valverdé
1e8a5d412f Refresh on window focus
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-05 00:44:13 +01:00
Julien Valverdé
86539f33f0 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-05 00:24:38 +01:00
Julien Valverdé
8fa24b1791 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-05 00:16:13 +01:00
Julien Valverdé
adaadf13b2 Working service query
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-04 23:18:35 +01:00
Julien Valverdé
3af7c3bf7a Query service work
Some checks failed
Lint / lint (push) Failing after 11s
2025-03-04 22:44:40 +01:00
Julien Valverdé
00b7228073 Refetch on focus
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-04 02:15:31 +01:00
Julien Valverdé
c2b2b1b96e Dependencies fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-04 02:04:29 +01:00
Julien Valverdé
74cf37e3a3 Query example
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-04 01:35:52 +01:00
Julien Valverdé
98091d4598 Refactoring
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-04 01:22:51 +01:00
Julien Valverdé
b2f1626268 Working query
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-04 01:19:42 +01:00
Julien Valverdé
40e8bf6a1f Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-03 19:42:33 +01:00
Julien Valverdé
9c96741c8e Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-03 03:37:39 +01:00
Julien Valverdé
3fa9b7d821 Working query
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-02 20:14:45 +01:00
Julien Valverdé
6b0f2f33cb Query work
Some checks failed
Lint / lint (push) Failing after 13s
2025-03-02 02:48:19 +01:00
Julien Valverdé
2e00db5778 Query work
Some checks failed
Lint / lint (push) Failing after 43s
2025-03-02 01:11:18 +01:00
Julien Valverdé
660f32a171 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-28 17:24:40 +01:00
Julien Valverdé
3f2639fda1 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-28 16:08:08 +01:00
Julien Valverdé
f76b3f333a Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-28 02:13:23 +01:00
Julien Valverdé
3b407c6b4f Query work
All checks were successful
Lint / lint (push) Successful in 17s
2025-02-28 01:06:11 +01:00
Julien Valverdé
b01b95a9d5 Query work
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-28 00:27:22 +01:00
Julien Valverdé
91b95ea6af useRefState refactpro
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-27 18:32:57 +01:00
Julien Valverdé
7c99d1ff3d Working useQuery
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-27 01:19:09 +01:00
Julien Valverdé
ae815553f2 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-02-26 23:57:03 +01:00
Julien Valverdé
86a96cbcce extension-query
Some checks failed
Lint / lint (push) Failing after 7s
2025-02-26 21:17:09 +01:00
Julien Valverdé
538b3a415d Cleanup
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-26 20:50:05 +01:00
Julien Valverdé
5b023678f4 Merge branch 'master' into next
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-26 20:47:00 +01:00
Julien Valverdé
9266697aa4 Merge branch 'next' of git.valverde.cloud:Thilawyn/reffuse into next
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-26 19:29:48 +01:00
Julien Valverdé
ad81bf9ed8 Cleanup
All checks were successful
Lint / lint (push) Successful in 11s
Test build / test-build (pull_request) Successful in 13s
2025-02-26 19:25:21 +01:00
Julien Valverdé
e92087e593 Turbo fix
All checks were successful
Lint / lint (push) Successful in 12s
Test build / test-build (pull_request) Successful in 13s
2025-02-26 19:23:49 +01:00
Julien Valverdé
e182e6ab5c README update
Some checks failed
Lint / lint (push) Successful in 12s
Test build / test-build (pull_request) Failing after 15s
2025-02-26 19:13:49 +01:00
Julien Valverdé
89175be558 README work
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-26 14:30:59 +01:00
Julien Valverdé
4df90a0f1c README work
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-26 14:05:12 +01:00
Julien Valverdé
693c7b2db8 Reffuse context refactoring
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-26 13:40:52 +01:00
Julien Valverdé
5f60d03d83 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-25 23:19:44 +01:00
Julien Valverdé
ea768218a0 Deps API change
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-25 23:11:58 +01:00
Julien Valverdé
3b4eb750ed Version bump
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-25 22:55:45 +01:00
Julien Valverdé
47aa130486 CI fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-25 22:53:07 +01:00
Julien Valverdé
02da3df8eb CI fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-25 22:45:55 +01:00
Julien Valverdé
8d276d2fbf Dependencies
Some checks failed
Lint / lint (push) Failing after 8s
2025-02-25 22:16:53 +01:00
Julien Valverdé
af077d34aa Turbo setup
Some checks failed
Lint / lint (push) Failing after 13s
2025-02-25 22:07:18 +01:00
Julien Valverdé
618cee4028 Callback tests
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-25 18:39:19 +01:00
Julien Valverdé
8244c34d2a Callback helpers
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-25 18:29:00 +01:00
Julien Valverdé
523d835d00 Fix
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-25 17:14:07 +01:00
Julien Valverdé
15e96b8fa9 Merge branch 'plugins' of git.valverde.cloud:Thilawyn/reffuse into plugins
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-25 14:49:22 +01:00
Julien Valverdé
44de864713 API update 2025-02-25 14:48:58 +01:00
Julien Valverdé
8e1f0a27cf Lockfile
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-25 13:45:09 +01:00
Julien Valverdé
8754020323 Working lazyref extension
Some checks failed
Lint / lint (push) Failing after 12s
2025-02-25 12:17:45 +01:00
Julien Valverdé
d9a01dae0f withLazyRef
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-25 11:22:49 +01:00
Julien Valverdé
8873e81f7c Dependencies
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-25 10:31:43 +01:00
Julien Valverdé
38fcafb15c Dependencies
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-25 10:21:34 +01:00
Julien Valverdé
411397c7de Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-02-24 21:30:13 +01:00
Julien Valverdé
85e7b54962 extension-lazyref
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-24 21:24:38 +01:00
Julien Valverdé
ce3989ab77 Extension fix
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-24 21:09:44 +01:00
Julien Valverdé
da0f6168f0 Fix
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-24 20:47:49 +01:00
Julien Valverdé
690dec1f1a Finalized
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-24 20:18:56 +01:00
Julien Valverdé
60274266da Extension work
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-24 20:00:02 +01:00
Julien Valverdé
28424b63cb Working extension
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-24 13:47:29 +01:00
Julien Valverdé
e063eb06f7 Extension work
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-24 13:17:10 +01:00
Julien Valverdé
fb5bb7fcef Cleanup
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-24 02:21:37 +01:00
Julien Valverdé
1f57f7d127 Tests
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-24 01:55:47 +01:00
Julien Valverdé
e8742e5aa6 Fix
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-23 23:38:24 +01:00
Julien Valverdé
be79d24d6e Tests
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-22 01:03:15 +01:00
Julien Valverdé
e1349e5e03 Tests
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-21 15:44:28 +01:00
Julien Valverdé
837dcbb1cb Extension work
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-21 15:27:11 +01:00
Julien Valverdé
8252b6cbdf Extension work
Some checks failed
Lint / lint (push) Failing after 10s
2025-02-21 05:22:19 +01:00
Julien Valverdé
256638bc06 ReffuseHelper
Some checks failed
Lint / lint (push) Failing after 11s
2025-02-21 04:22:48 +01:00
Julien Valverdé
c0097bbe81 Extension tests
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-20 14:57:46 +01:00
Julien Valverdé
febeaa05d0 ReffuseExtension
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-20 14:12:56 +01:00
Julien Valverdé
a71640d493 Cleanup
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-20 00:41:37 +01:00
Julien Valverdé
b636a709f3 Tests
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-20 00:39:15 +01:00
Julien Valverdé
fffbd01b5e Pipeable API tests
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-20 00:21:43 +01:00
Julien Valverdé
36d5414d10 Fix
All checks were successful
Lint / lint (push) Successful in 44s
2025-02-19 23:59:34 +01:00
Julien Valverdé
65810a6d79 usePromise
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-19 23:44:02 +01:00
Julien Valverdé
9e7b30fbb4 useFork refactoring
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-19 23:24:15 +01:00
Julien Valverdé
6c843562ab usePromiseScoped fork implementation
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-18 23:47:32 +01:00
Julien Valverdé
809f512d11 Fix
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-18 22:33:49 +01:00
Julien Valverdé
e71239b903 usePromiseScoped
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-18 22:28:49 +01:00
Julien Valverdé
bfcc097882 usePromise
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-18 15:25:46 +01:00
Julien Valverdé
933b061b5d Promise tests
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-18 05:18:34 +01:00
Julien Valverdé
734c84824c Implement Pipeable
All checks were successful
Lint / lint (push) Successful in 10s
2025-02-18 04:30:10 +01:00
Julien Valverdé
e83e86f8f1 Promise tests
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-18 02:56:05 +01:00
Julien Valverdé
bebbc1d7de Promise tests
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-18 02:23:40 +01:00
Julien Valverdé
a7a0951b61 Dependencies fix
All checks were successful
Lint / lint (push) Successful in 11s
2025-02-18 01:08:26 +01:00
Julien Valverdé
1b1a1961bc Dependencies upgrade
Some checks failed
Lint / lint (push) Failing after 13s
2025-02-17 00:16:41 +01:00
34 changed files with 603 additions and 830 deletions

540
bun.lock

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@reffuse/monorepo",
"packageManager": "bun@1.2.12",
"packageManager": "bun@1.2.9",
"private": true,
"workspaces": [
"./packages/*"
@@ -15,9 +15,9 @@
"clean:node": "rm -rf node_modules"
},
"devDependencies": {
"npm-check-updates": "^18.0.1",
"npm-check-updates": "^17.1.18",
"npm-sort": "^0.0.4",
"turbo": "^2.5.3",
"turbo": "^2.5.0",
"typescript": "^5.8.3"
}
}

View File

@@ -11,41 +11,41 @@
"preview": "vite preview"
},
"devDependencies": {
"@eslint/js": "^9.26.0",
"@tanstack/react-router": "^1.120.2",
"@tanstack/react-router-devtools": "^1.120.2",
"@tanstack/router-plugin": "^1.120.2",
"@eslint/js": "^9.24.0",
"@tanstack/react-router": "^1.115.3",
"@tanstack/react-router-devtools": "^1.115.3",
"@tanstack/router-plugin": "^1.115.3",
"@thilawyn/thilaschema": "^0.1.4",
"@types/react": "^19.1.3",
"@types/react-dom": "^19.1.3",
"@vitejs/plugin-react": "^4.4.1",
"eslint": "^9.26.0",
"@types/react": "^19.1.1",
"@types/react-dom": "^19.1.2",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.24.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.1.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^16.0.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"typescript-eslint": "^8.32.0",
"vite": "^6.3.5"
"typescript-eslint": "^8.29.1",
"vite": "^6.2.6"
},
"dependencies": {
"@effect/platform": "^0.80.21",
"@effect/platform-browser": "^0.60.12",
"@effect/platform": "^0.80.8",
"@effect/platform-browser": "^0.59.8",
"@radix-ui/themes": "^3.2.1",
"@reffuse/extension-lazyref": "workspace:*",
"@reffuse/extension-query": "workspace:*",
"@typed/async-data": "^0.13.1",
"@typed/id": "^0.17.2",
"@typed/lazy-ref": "^0.3.3",
"effect": "^3.14.21",
"lucide-react": "^0.508.0",
"effect": "^3.14.8",
"lucide-react": "^0.487.0",
"mobx": "^6.13.7",
"reffuse": "workspace:*"
},
"overrides": {
"effect": "^3.14.21",
"@effect/platform": "^0.80.21",
"@effect/platform-browser": "^0.60.12",
"effect": "^3.14.8",
"@effect/platform": "^0.80.8",
"@effect/platform-browser": "^0.59.8",
"@typed/lazy-ref": "^0.3.3",
"@typed/async-data": "^0.13.1"
}

View File

@@ -1,7 +1,7 @@
import { AlertDialog, Button, Flex, Text } from "@radix-ui/themes"
import { Cause, Console, Effect, Either, flow, Match, Option, Stream } from "effect"
import { useState } from "react"
import { AppQueryClient } from "./query"
import { AppQueryErrorHandler } from "./query"
import { R } from "./reffuse"
@@ -9,8 +9,8 @@ export function VQueryErrorHandler() {
const [open, setOpen] = useState(false)
const error = R.useSubscribeStream(
R.useMemo(() => AppQueryClient.pipe(
Effect.map(client => client.errorHandler.errors.pipe(
R.useMemo(() => AppQueryErrorHandler.pipe(
Effect.map(handler => handler.errors.pipe(
Stream.changes,
Stream.tap(Console.error),
Stream.tap(() => Effect.sync(() => setOpen(true))),

View File

@@ -3,11 +3,12 @@ import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser"
import { LazyRefExtension } from "@reffuse/extension-lazyref"
import { QueryExtension } from "@reffuse/extension-query"
import { Reffuse, ReffuseContext } from "reffuse"
import { AppQueryClient } from "./query"
import { AppQueryClient, AppQueryErrorHandler } from "./query"
export const RootContext = ReffuseContext.make<
| AppQueryClient
| AppQueryErrorHandler
| Clipboard.Clipboard
| Geolocation.Geolocation
| Permissions.Permissions

View File

@@ -19,7 +19,6 @@ import { Route as LazyrefImport } from './routes/lazyref'
import { Route as CountImport } from './routes/count'
import { Route as BlankImport } from './routes/blank'
import { Route as IndexImport } from './routes/index'
import { Route as StreamsPullImport } from './routes/streams/pull'
import { Route as QueryUsequeryImport } from './routes/query/usequery'
import { Route as QueryUsemutationImport } from './routes/query/usemutation'
import { Route as QueryServiceImport } from './routes/query/service'
@@ -74,12 +73,6 @@ const IndexRoute = IndexImport.update({
getParentRoute: () => rootRoute,
} as any)
const StreamsPullRoute = StreamsPullImport.update({
id: '/streams/pull',
path: '/streams/pull',
getParentRoute: () => rootRoute,
} as any)
const QueryUsequeryRoute = QueryUsequeryImport.update({
id: '/query/usequery',
path: '/query/usequery',
@@ -179,13 +172,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof QueryUsequeryImport
parentRoute: typeof rootRoute
}
'/streams/pull': {
id: '/streams/pull'
path: '/streams/pull'
fullPath: '/streams/pull'
preLoaderRoute: typeof StreamsPullImport
parentRoute: typeof rootRoute
}
}
}
@@ -203,7 +189,6 @@ export interface FileRoutesByFullPath {
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
'/streams/pull': typeof StreamsPullRoute
}
export interface FileRoutesByTo {
@@ -218,7 +203,6 @@ export interface FileRoutesByTo {
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
'/streams/pull': typeof StreamsPullRoute
}
export interface FileRoutesById {
@@ -234,7 +218,6 @@ export interface FileRoutesById {
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
'/streams/pull': typeof StreamsPullRoute
}
export interface FileRouteTypes {
@@ -251,7 +234,6 @@ export interface FileRouteTypes {
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
| '/streams/pull'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
@@ -265,7 +247,6 @@ export interface FileRouteTypes {
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
| '/streams/pull'
id:
| '__root__'
| '/'
@@ -279,7 +260,6 @@ export interface FileRouteTypes {
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
| '/streams/pull'
fileRoutesById: FileRoutesById
}
@@ -295,7 +275,6 @@ export interface RootRouteChildren {
QueryServiceRoute: typeof QueryServiceRoute
QueryUsemutationRoute: typeof QueryUsemutationRoute
QueryUsequeryRoute: typeof QueryUsequeryRoute
StreamsPullRoute: typeof StreamsPullRoute
}
const rootRouteChildren: RootRouteChildren = {
@@ -310,7 +289,6 @@ const rootRouteChildren: RootRouteChildren = {
QueryServiceRoute: QueryServiceRoute,
QueryUsemutationRoute: QueryUsemutationRoute,
QueryUsequeryRoute: QueryUsequeryRoute,
StreamsPullRoute: StreamsPullRoute,
}
export const routeTree = rootRoute
@@ -333,8 +311,7 @@ export const routeTree = rootRoute
"/todos",
"/query/service",
"/query/usemutation",
"/query/usequery",
"/streams/pull"
"/query/usequery"
]
},
"/": {
@@ -369,9 +346,6 @@ export const routeTree = rootRoute
},
"/query/usequery": {
"filePath": "query/usequery.tsx"
},
"/streams/pull": {
"filePath": "streams/pull.tsx"
}
}
}

View File

@@ -1,6 +1,6 @@
import { R } from "@/reffuse"
import { createFileRoute } from "@tanstack/react-router"
import { Effect, Ref } from "effect"
import { Ref } from "effect"
export const Route = createFileRoute("/count")({
@@ -11,13 +11,14 @@ function Count() {
const runSync = R.useRunSync()
const countRef = R.useRef(() => Effect.succeed(0))
const [count] = R.useSubscribeRefs(countRef)
const countRef = R.useRef(0)
const [count] = R.useRefState(countRef)
return (
<div className="container mx-auto">
<button onClick={() => runSync(Ref.update(countRef, count => count + 1))}>
{/* <button onClick={() => setCount((count) => count + 1)}> */}
<button onClick={() => Ref.update(countRef, count => count + 1).pipe(runSync)}>
count is {count}
</button>
</div>

View File

@@ -14,7 +14,7 @@ export const Route = createFileRoute("/query/service")({
function RouteComponent() {
const query = R.useQuery({
key: R.useStreamFromReactiveValues(["uuid4", 10 as number]),
key: R.useStreamFromValues(["uuid4", 10 as number]),
query: ([, count]) => Console.log(`Querying ${ count } IDs...`).pipe(
Effect.andThen(Effect.sleep("500 millis")),
Effect.andThen(HttpClient.get(`https://www.uuidtools.com/api/generate/v4/count/${ count }`)),

View File

@@ -20,7 +20,7 @@ function RouteComponent() {
const [count, setCount] = useState(1)
const query = R.useQuery({
key: R.useStreamFromReactiveValues(["uuid4", count]),
key: R.useStreamFromValues(["uuid4", count]),
query: ([, count]) => Console.log(`Querying ${ count } IDs...`).pipe(
Effect.andThen(Effect.sleep("500 millis")),
Effect.andThen(HttpClient.get(`https://www.uuidtools.com/api/generate/v4/count/${ count }`)),

View File

@@ -1,34 +0,0 @@
import { R } from "@/reffuse"
import { Button, Flex, Text } from "@radix-ui/themes"
import { createFileRoute } from "@tanstack/react-router"
import { Chunk, Effect, Exit, Option, Queue, Random, Scope, Stream } from "effect"
import { useMemo, useState } from "react"
export const Route = createFileRoute("/streams/pull")({
component: RouteComponent
})
function RouteComponent() {
const stream = useMemo(() => Stream.repeatEffect(Random.nextInt), [])
const streamScope = R.useScope([stream], { finalizerExecutionMode: "fork" })
const queue = R.useMemo(() => Effect.provideService(Stream.toQueueOfElements(stream), Scope.Scope, streamScope), [streamScope])
const [value, setValue] = useState(Option.none<number>())
const pullLatest = R.useCallbackSync(() => Queue.takeAll(queue).pipe(
Effect.flatMap(Chunk.last),
Effect.flatMap(Exit.matchEffect({
onSuccess: Effect.succeed,
onFailure: Effect.fail,
})),
Effect.tap(v => Effect.sync(() => setValue(Option.some(v)))),
), [queue])
return (
<Flex direction="column" align="center" gap="2">
{Option.isSome(value) && <Text>{value.value}</Text>}
<Button onClick={pullLatest}>Pull latest</Button>
</Flex>
)
}

View File

@@ -2,11 +2,7 @@ import { R } from "@/reffuse"
import { Button, Flex, Text } from "@radix-ui/themes"
import { createFileRoute } from "@tanstack/react-router"
import { GetRandomValues, makeUuid4 } from "@typed/id"
import { Console, Effect, Option, Scope } from "effect"
import { useEffect, useState } from "react"
const makeUuid = Effect.provide(makeUuid4, GetRandomValues.CryptoRandom)
import { Console, Effect, Ref } from "effect"
export const Route = createFileRoute("/tests")({
@@ -14,34 +10,40 @@ export const Route = createFileRoute("/tests")({
})
function RouteComponent() {
const runSync = R.useRunSync()
// const value = R.useMemoScoped(Effect.addFinalizer(() => Console.log("cleanup")).pipe(
// Effect.andThen(makeUuid4),
// Effect.provide(GetRandomValues.CryptoRandom),
// ), [])
// console.log(value)
const [uuid, setUuid] = useState(R.useMemo(() => makeUuid, []))
const generateUuid = R.useCallbackSync(() => makeUuid.pipe(
Effect.tap(v => Effect.sync(() => setUuid(v)))
R.useFork(() => Effect.addFinalizer(() => Console.log("cleanup")).pipe(
Effect.andThen(Console.log("ouient")),
Effect.delay("1 second"),
), [])
const uuidStream = R.useStreamFromReactiveValues([uuid])
const uuidStreamLatestValue = R.useSubscribeStream(uuidStream)
const scope = R.useScope([uuid])
const uuidRef = R.useRef("none")
const anotherRef = R.useRef(69)
const logValue = R.useCallbackSync(Effect.fn(function*(value: string) {
yield* Effect.log(value)
}), [])
const generateUuid = R.useCallbackSync(() => makeUuid4.pipe(
Effect.provide(GetRandomValues.CryptoRandom),
Effect.flatMap(v => Ref.set(uuidRef, v)),
), [])
useEffect(() => Effect.addFinalizer(() => Console.log("Scope cleanup!")).pipe(
Effect.andThen(Console.log("Scope changed")),
Effect.provideService(Scope.Scope, scope),
runSync,
), [scope, runSync])
return (
<Flex direction="column" justify="center" align="center" gap="2">
<Text>{uuid}</Text>
<Button onClick={generateUuid}>Generate UUID</Button>
<Text>
{Option.match(uuidStreamLatestValue, {
onSome: ([v]) => v,
onNone: () => <></>,
})}
</Text>
<Flex direction="row" justify="center" align="center" gap="2">
<R.SubscribeRefs refs={[uuidRef, anotherRef]}>
{(uuid, anotherRef) => <Text>{uuid} / {anotherRef}</Text>}
</R.SubscribeRefs>
<Button onClick={() => logValue("test")}>Log value</Button>
<Button onClick={() => generateUuid()}>Generate UUID</Button>
</Flex>
)
}

View File

@@ -16,7 +16,7 @@ export function VTodos() {
), [])
const todosRef = R.useMemo(() => TodosState.TodosState.pipe(Effect.map(state => state.todos)), [])
const [todos] = R.useSubscribeRefs(todosRef)
const [todos] = R.useRefState(todosRef)
return (

View File

@@ -0,0 +1,9 @@
# LazyRef extension for Reffuse
Extension to integrate `@typed/lazy-ref` with Reffuse.
## Peer dependencies
- `@typed/lazy-ref`
- `reffuse` 0.1.3+
- `effect` 3.13+
- `react` & `@types/react` 19+

View File

@@ -0,0 +1,40 @@
{
"name": "@reffuse/extension-form",
"version": "0.1.0",
"type": "module",
"files": [
"./README.md",
"./dist"
],
"license": "MIT",
"repository": {
"url": "git+https://github.com/Thiladev/reffuse.git"
},
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./*": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"
}
},
"scripts": {
"build": "tsc",
"lint:tsc": "tsc --noEmit",
"pack": "npm pack",
"clean:cache": "rm -f tsconfig.tsbuildinfo",
"clean:dist": "rm -rf dist",
"clean:node": "rm -rf node_modules"
},
"devDependencies": {
"reffuse": "workspace:*"
},
"peerDependencies": {
"effect": "^3.13.0",
"react": "^19.0.0",
"reffuse": "^0.1.7"
}
}

View File

@@ -0,0 +1,9 @@
import { ReffuseExtension, type ReffuseNamespace } from "reffuse"
export const FormExtension = ReffuseExtension.make(() => ({
useForm<A, E, R>(
this: ReffuseNamespace.ReffuseNamespace<R>,
) {
},
}))

View File

@@ -0,0 +1 @@
export * from "./FormExtension.js"

View File

@@ -0,0 +1,6 @@
import { Schema } from "effect"
export interface Form<A, I, R> {
readonly schema: Schema.Schema<A, I, R>
}

View File

@@ -0,0 +1,69 @@
import type { Effect, Schema } from "effect"
import type * as Formify from "./Formify.js"
export interface FormField<S extends Schema.Schema.Any> {
readonly schema: S
}
export const makeFormField = <S extends Schema.Schema.Any>(
schema: S,
get: Effect.Effect<S["Type"]>,
set: (value: S["Type"]) => Effect.Effect<void>,
): FormField<S> => {
}
export interface UnionFormField<
S extends Schema.Union<Members>,
Members extends ReadonlyArray<Schema.Schema.All>,
> extends FormField<S> {
readonly member: Formify.Formify<Members[number]>
}
export interface TupleFormField<
S extends Schema.TupleType<Elements, Rest>,
Elements extends Schema.TupleType.Elements,
Rest extends Schema.TupleType.Rest,
> extends FormField<S> {
readonly elements: [...{ readonly [K in keyof Elements]: Formify.Formify<Elements[K]> }]
}
export interface ArrayFormField<
S extends Schema.Array$<Value>,
Value extends Schema.Schema.Any,
> extends FormField<S> {
readonly elements: readonly Formify.Formify<Value>[]
}
export type StructFormField<
S extends Schema.Struct<Fields>,
Fields extends Schema.Struct.Fields,
> = (
& FormField<S>
& { readonly fields: { readonly [K in keyof Fields]: Formify.Formify<Fields[K]> } }
& {
[K in keyof Fields as Fields[K] extends
Schema.tag<infer _> ? K : never
]: Fields[K] extends
Schema.tag<infer Tag> ? Tag : never
}
)
export interface GenericFormField<S extends Schema.Schema.Any> extends FormField<S> {
}
export interface PropertySignatureFormField<
S extends Schema.PropertySignature<TypeToken, Type, Key, EncodedToken, Encoded, HasDefault, R>,
TypeToken extends Schema.PropertySignature.Token,
Type,
Key extends PropertyKey,
EncodedToken extends Schema.PropertySignature.Token,
Encoded,
HasDefault extends boolean = false,
R = never,
> {
readonly propertySignature: S
readonly value: Type
}

View File

@@ -0,0 +1,51 @@
import { Schema } from "effect"
import type * as FormField from "./FormField.js"
export type Formify<S> = (
S extends Schema.Union<infer Members> ? FormField.UnionFormField<S, Members> :
S extends Schema.TupleType<infer Elements, infer Rest> ? FormField.TupleFormField<S, Elements, Rest> :
S extends Schema.Array$<infer Value> ? FormField.ArrayFormField<S, Value> :
S extends Schema.Struct<infer Fields> ? FormField.StructFormField<S, Fields> :
S extends Schema.Schema.Any ? FormField.GenericFormField<S> :
S extends Schema.PropertySignature<
infer TypeToken,
infer Type,
infer Key,
infer EncodedToken,
infer Encoded,
infer HasDefault,
infer R
> ? FormField.PropertySignatureFormField<S, TypeToken, Type, Key, EncodedToken, Encoded, HasDefault, R> :
never
)
const Login = Schema.Union(
Schema.Struct({
_tag: Schema.tag("ByEmail"),
email: Schema.String,
password: Schema.RedactedFromSelf(Schema.String),
}),
Schema.Struct({
_tag: Schema.tag("ByPhone"),
phone: Schema.String,
password: Schema.RedactedFromSelf(Schema.String),
}),
Schema.TaggedStruct("ByKey", {
id: Schema.String,
password: Schema.RedactedFromSelf(Schema.String),
}),
)
type LoginForm = Formify<typeof Login>
declare const loginForm: LoginForm
switch (loginForm.member._tag) {
case "ByEmail":
loginForm.member
break
case "ByPhone":
break
}

View File

@@ -0,0 +1,37 @@
import { Array, Predicate, Record, Schema, Tuple } from "effect"
export const isTupleSchema = (u: unknown): u is Schema.Tuple<any> => (
Schema.isSchema(u) &&
Predicate.hasProperty(u, "elements") && Array.isArray(u.elements) &&
Predicate.hasProperty(u, "rest") && Array.isArray(u.rest)
)
export const isArraySchema = (u: unknown): u is Schema.Array$<any> => (
Schema.isSchema(u) &&
Predicate.hasProperty(u, "elements") && Array.isArray(u.elements) && Array.isEmptyArray(u.elements) &&
Predicate.hasProperty(u, "rest") && Array.isArray(u.rest) && Tuple.isTupleOf(u.rest, 1) &&
Predicate.hasProperty(u, "value")
)
export const isStructSchema = (u: unknown): u is Schema.Struct<any> => (
Schema.isSchema(u) &&
Predicate.hasProperty(u, "fields") && Predicate.isObject(u.fields) &&
Predicate.hasProperty(u, "records") && Array.isArray(u.records) && Array.isEmptyArray(u.records)
)
export const isRecordSchema = (u: unknown): u is Schema.Record$<any, any> => (
Schema.isSchema(u) &&
Predicate.hasProperty(u, "fields") && Predicate.isObject(u.fields) && Record.isEmptyRecord(u.fields) &&
Predicate.hasProperty(u, "records") && Array.isArray(u.records) &&
Predicate.hasProperty(u, "key") &&
Predicate.hasProperty(u, "value")
)
const myTuple = Schema.Tuple(Schema.String)
const myArray = Schema.Array(Schema.String)
const myStruct = Schema.Struct({})
const myRecord = Schema.Record({ key: Schema.String, value: Schema.String })
console.log(isArraySchema(myTuple))

View File

@@ -0,0 +1 @@
export * as Form from "./Form.js"

View File

@@ -0,0 +1,33 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "NodeNext",
"moduleDetection": "force",
"jsx": "react-jsx",
// "allowJs": true,
// Bundler mode
"moduleResolution": "NodeNext",
// "allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
// "noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false,
// Build
"outDir": "./dist",
"declaration": true
},
"include": ["./src"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@reffuse/extension-lazyref",
"version": "0.1.4",
"version": "0.1.3",
"type": "module",
"files": [
"./README.md",
@@ -37,6 +37,6 @@
"@types/react": "^19.0.0",
"effect": "^3.13.0",
"react": "^19.0.0",
"reffuse": "^0.1.8"
"reffuse": "^0.1.7"
}
}

View File

@@ -1,8 +1,7 @@
import * as LazyRef from "@typed/lazy-ref"
import { Effect, pipe, Stream } from "effect"
import * as React from "react"
import { ReffuseExtension, type ReffuseNamespace } from "reffuse"
import { SetStateAction } from "reffuse/types"
import { ReffuseExtension, type ReffuseNamespace, SetStateAction } from "reffuse"
export const LazyRefExtension = ReffuseExtension.make(() => ({

View File

@@ -1,4 +1,4 @@
import { Cause, Context, Effect, identity, Layer, PubSub, Stream } from "effect"
import { Cause, Context, Effect, identity, Layer, Queue, Stream } from "effect"
import type { Mutable } from "effect/Types"
@@ -36,17 +36,17 @@ export const Service = <Self, HandledE = never>() => (
const TagClass = Context.Tag(id)() as ServiceResult<Self, Id, FallbackA, HandledE>
(TagClass as Mutable<typeof TagClass>).Live = Layer.effect(TagClass, Effect.gen(function*() {
const pubsub = yield* PubSub.unbounded<Cause.Cause<HandledE>>()
const errors = Stream.fromPubSub(pubsub)
const queue = yield* Queue.unbounded<Cause.Cause<HandledE>>()
const errors = Stream.fromQueue(queue)
const handle = <A, E, R>(
self: Effect.Effect<A, E, R>
): Effect.Effect<A | FallbackA, Exclude<E, HandledE>, R> => f(
self as unknown as Effect.Effect<never, HandledE, never>,
(failure: HandledE) => PubSub.publish(pubsub, Cause.fail(failure)).pipe(
(failure: HandledE) => Queue.offer(queue, Cause.fail(failure)).pipe(
Effect.andThen(Effect.failCause(Cause.empty))
),
(defect: unknown) => PubSub.publish(pubsub, Cause.die(defect)).pipe(
(defect: unknown) => Queue.offer(queue, Cause.die(defect)).pipe(
Effect.andThen(Effect.failCause(Cause.empty))
),
)

View File

@@ -1,6 +1,6 @@
{
"name": "reffuse",
"version": "0.1.10",
"version": "0.1.7",
"type": "module",
"files": [
"./README.md",
@@ -16,10 +16,6 @@
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./types": {
"types": "./dist/types/index.d.ts",
"default": "./dist/types/index.js"
},
"./*": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"

View File

@@ -1,7 +1,7 @@
import type * as ReffuseContext from "./ReffuseContext.js"
import type * as ReffuseExtension from "./ReffuseExtension.js"
import * as ReffuseNamespace from "./ReffuseNamespace.js"
import type { Merge, StaticType } from "./utils.js"
import type { Merge, StaticType } from "./types.js"
export class Reffuse extends ReffuseNamespace.makeClass() {}

View File

@@ -1,8 +1,8 @@
import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, type Layer, Match, Option, pipe, Pipeable, PubSub, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect"
import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, type Layer, Option, pipe, Pipeable, Queue, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect"
import * as React from "react"
import * as ReffuseContext from "./ReffuseContext.js"
import * as ReffuseRuntime from "./ReffuseRuntime.js"
import { type PropertyPath, SetStateAction, SubscriptionSubRef } from "./types/index.js"
import * as SetStateAction from "./SetStateAction.js"
export interface RenderOptions {
@@ -14,20 +14,11 @@ export interface ScopeOptions {
readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy
}
export interface UseScopeOptions extends RenderOptions, ScopeOptions {
readonly finalizerExecutionMode?: "sync" | "fork"
}
export type RefsA<T extends readonly SubscriptionRef.SubscriptionRef<any>[]> = {
[K in keyof T]: Effect.Effect.Success<T[K]>
}
export abstract class ReffuseNamespace<R> {
declare ["constructor"]: ReffuseNamespaceClass<R>
constructor() {
this.SubRef = this.SubRef.bind(this as any) as any
this.SubscribeRefs = this.SubscribeRefs.bind(this as any) as any
this.RefState = this.RefState.bind(this as any) as any
this.SubscribeStream = this.SubscribeStream.bind(this as any) as any
@@ -92,55 +83,6 @@ export abstract class ReffuseNamespace<R> {
), [runtime, context])
}
useScope<R>(
this: ReffuseNamespace<R>,
deps: React.DependencyList = [],
options?: UseScopeOptions,
): Scope.Scope {
const runSync = this.useRunSync()
const runFork = this.useRunFork()
const [isInitialRun, initialScope] = React.useMemo(() => runSync(Effect.all([
Ref.make(true),
Scope.make(options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential),
])), [])
const [scope, setScope] = React.useState(initialScope)
React.useEffect(() => isInitialRun.pipe(
Effect.if({
onTrue: () => Effect.as(
Ref.set(isInitialRun, false),
() => Scope.close(initialScope, Exit.void).pipe(
effect => Match.value(options?.finalizerExecutionMode ?? "sync").pipe(
Match.when("sync", () => { runSync(effect) }),
Match.when("fork", () => { runFork(effect) }),
Match.exhaustive,
)
),
),
onFalse: () => Scope.make(options?.finalizerExecutionStrategy).pipe(
Effect.tap(v => Effect.sync(() => setScope(v))),
Effect.map(v => () => Scope.close(v, Exit.void).pipe(
effect => Match.value(options?.finalizerExecutionMode ?? "sync").pipe(
Match.when("sync", () => { runSync(effect) }),
Match.when("fork", () => { runFork(effect) }),
Match.exhaustive,
)
)),
),
}),
runSync,
), [
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork],
...deps,
])
return scope
}
/**
* Reffuse equivalent to `React.useMemo`.
*
@@ -164,6 +106,53 @@ export abstract class ReffuseNamespace<R> {
])
}
useMemoScoped<A, E, R>(
this: ReffuseNamespace<R>,
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
deps: React.DependencyList,
options?: RenderOptions & ScopeOptions,
): A {
const runSync = this.useRunSync()
const [isInitialRun, initialScope, initialValue] = React.useMemo(() => Effect.Do.pipe(
Effect.bind("isInitialRun", () => Ref.make(true)),
Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy)),
Effect.bind("value", ({ scope }) => Effect.provideService(effect(), Scope.Scope, scope)),
Effect.map(({ isInitialRun, scope, value }) => [isInitialRun, scope, value] as const),
runSync,
), [])
const [value, setValue] = React.useState(initialValue)
React.useEffect(() => isInitialRun.pipe(
Effect.if({
onTrue: () => Ref.set(isInitialRun, false).pipe(
Effect.map(() =>
() => runSync(Scope.close(initialScope, Exit.void))
)
),
onFalse: () => Effect.Do.pipe(
Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy)),
Effect.bind("value", ({ scope }) => Effect.provideService(effect(), Scope.Scope, scope)),
Effect.tap(({ value }) =>
Effect.sync(() => setValue(value))
),
Effect.map(({ scope }) =>
() => runSync(Scope.close(scope, Exit.void))
),
),
}),
runSync,
), [
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
...deps,
])
return value
}
/**
* Reffuse equivalent to `React.useEffect`.
*
@@ -384,34 +373,14 @@ export abstract class ReffuseNamespace<R> {
])
}
useRef<A, E, R>(
this: ReffuseNamespace<R>,
initialValue: () => Effect.Effect<A, E, R>,
): SubscriptionRef.SubscriptionRef<A> {
return this.useMemo(
() => Effect.flatMap(initialValue(), SubscriptionRef.make),
[],
{ doNotReExecuteOnRuntimeOrContextChange: true }, // Do not recreate the ref when the context changes
)
}
useRefFromReactiveValue<A, R>(
useRef<A, R>(
this: ReffuseNamespace<R>,
value: A,
): SubscriptionRef.SubscriptionRef<A> {
const ref = this.useRef(() => Effect.succeed(value))
this.useEffect(() => Ref.set(ref, value), [value], { doNotReExecuteOnRuntimeOrContextChange: true })
return ref
}
useSubRef<B, const P extends PropertyPath.Paths<B>, R>(
this: ReffuseNamespace<R>,
parent: SubscriptionRef.SubscriptionRef<B>,
path: P,
): SubscriptionSubRef.SubscriptionSubRef<PropertyPath.ValueFromPath<B, P>, B> {
return React.useMemo(
() => SubscriptionSubRef.makeFromPath(parent, path),
[parent],
return this.useMemo(
() => SubscriptionRef.make(value),
[],
{ doNotReExecuteOnRuntimeOrContextChange: true }, // Do not recreate the ref when the context changes
)
}
@@ -421,18 +390,18 @@ export abstract class ReffuseNamespace<R> {
>(
this: ReffuseNamespace<R>,
...refs: Refs
): RefsA<Refs> {
): [...{ [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }] {
const [reactStateValue, setReactStateValue] = React.useState(this.useMemo(
() => Effect.all(refs as readonly SubscriptionRef.SubscriptionRef<any>[]),
[],
{ doNotReExecuteOnRuntimeOrContextChange: true },
) as RefsA<Refs>)
) as [...{ [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }])
this.useFork(() => pipe(
refs.map(ref => Stream.changesWith(ref.changes, (x, y) => x === y)),
streams => Stream.zipLatestAll(...streams),
Stream.runForEach(v =>
Effect.sync(() => setReactStateValue(v as RefsA<Refs>))
Effect.sync(() => setReactStateValue(v as [...{ [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }]))
),
), refs)
@@ -470,75 +439,35 @@ export abstract class ReffuseNamespace<R> {
return [reactStateValue, setValue]
}
useStreamFromReactiveValues<const A extends React.DependencyList, R>(
useStreamFromValues<const A extends React.DependencyList, R>(
this: ReffuseNamespace<R>,
values: A,
): Stream.Stream<A> {
const scope = this.useScope()
const [queue, stream] = this.useMemo(() => Queue.unbounded<A>().pipe(
Effect.map(queue => [queue, Stream.fromQueue(queue)] as const)
), [])
const { latest, pubsub, stream } = this.useMemo(() => Effect.Do.pipe(
Effect.bind("latest", () => Ref.make(values)),
Effect.bind("pubsub", () => Effect.acquireRelease(PubSub.unbounded<A>(), PubSub.shutdown)),
Effect.let("stream", ({ latest, pubsub }) => Ref.get(latest).pipe(
Effect.flatMap(a => Effect.map(
Stream.fromPubSub(pubsub, { scoped: true }),
s => Stream.concat(Stream.make(a), s),
)),
Stream.unwrapScoped,
)),
Effect.provideService(Scope.Scope, scope),
), [scope], { doNotReExecuteOnRuntimeOrContextChange: true })
this.useEffect(() => Ref.set(latest, values).pipe(
Effect.andThen(PubSub.publish(pubsub, values)),
Effect.unlessEffect(PubSub.isShutdown(pubsub)),
), values, { doNotReExecuteOnRuntimeOrContextChange: true })
this.useEffect(() => Queue.offer(queue, values), values)
return stream
}
useSubscribeStream<A, E, R>(
useSubscribeStream<A, InitialA extends A | undefined, E, R>(
this: ReffuseNamespace<R>,
stream: Stream.Stream<A, E, R>,
): Option.Option<A>
useSubscribeStream<A, E, IE, R>(
this: ReffuseNamespace<R>,
stream: Stream.Stream<A, E, R>,
initialValue: () => Effect.Effect<A, IE, R>,
): Option.Some<A>
useSubscribeStream<A, E, IE, R>(
this: ReffuseNamespace<R>,
stream: Stream.Stream<A, E, R>,
initialValue?: () => Effect.Effect<A, IE, R>,
): Option.Option<A> {
const [reactStateValue, setReactStateValue] = React.useState(this.useMemo(
() => initialValue
? Effect.map(initialValue(), Option.some)
: Effect.succeed(Option.none()),
[],
{ doNotReExecuteOnRuntimeOrContextChange: true },
))
initialValue?: InitialA,
): InitialA extends A ? Option.Some<A> : Option.Option<A> {
const [reactStateValue, setReactStateValue] = React.useState<Option.Option<A>>(Option.fromNullable(initialValue))
this.useFork(() => Stream.runForEach(
Stream.changesWith(stream, (x, y) => x === y),
v => Effect.sync(() => setReactStateValue(Option.some(v))),
), [stream])
return reactStateValue
return reactStateValue as InitialA extends A ? Option.Some<A> : Option.Option<A>
}
SubRef<B, const P extends PropertyPath.Paths<B>, R>(
this: ReffuseNamespace<R>,
props: {
readonly parent: SubscriptionRef.SubscriptionRef<B>,
readonly path: P,
readonly children: (subRef: SubscriptionSubRef.SubscriptionSubRef<PropertyPath.ValueFromPath<B, P>, B>) => React.ReactNode
},
): React.ReactNode {
return props.children(this.useSubRef(props.parent, props.path))
}
SubscribeRefs<
const Refs extends readonly SubscriptionRef.SubscriptionRef<any>[],
R,
@@ -546,7 +475,7 @@ export abstract class ReffuseNamespace<R> {
this: ReffuseNamespace<R>,
props: {
readonly refs: Refs
readonly children: (...args: RefsA<Refs>) => React.ReactNode
readonly children: (...args: [...{ [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }]) => React.ReactNode
},
): React.ReactNode {
return props.children(...this.useSubscribeRefs(...props.refs))
@@ -562,30 +491,15 @@ export abstract class ReffuseNamespace<R> {
return props.children(this.useRefState(props.ref))
}
SubscribeStream<A, E, R>(
SubscribeStream<A, InitialA extends A | undefined, E, R>(
this: ReffuseNamespace<R>,
props: {
readonly stream: Stream.Stream<A, E, R>
readonly children: (latestValue: Option.Option<A>) => React.ReactNode
},
): React.ReactNode
SubscribeStream<A, E, IE, R>(
this: ReffuseNamespace<R>,
props: {
readonly stream: Stream.Stream<A, E, R>
readonly initialValue: () => Effect.Effect<A, IE, R>
readonly children: (latestValue: Option.Some<A>) => React.ReactNode
},
): React.ReactNode
SubscribeStream<A, E, IE, R>(
this: ReffuseNamespace<R>,
props: {
readonly stream: Stream.Stream<A, E, R>
readonly initialValue?: () => Effect.Effect<A, IE, R>
readonly children: (latestValue: Option.Some<A>) => React.ReactNode
readonly initialValue?: InitialA
readonly children: (latestValue: InitialA extends A ? Option.Some<A> : Option.Option<A>) => React.ReactNode
},
): React.ReactNode {
return props.children(this.useSubscribeStream(props.stream, props.initialValue as () => Effect.Effect<A, IE, R>))
return props.children(this.useSubscribeStream(props.stream, props.initialValue))
}
}

View File

@@ -3,3 +3,4 @@ export * as ReffuseContext from "./ReffuseContext.js"
export * as ReffuseExtension from "./ReffuseExtension.js"
export * as ReffuseNamespace from "./ReffuseNamespace.js"
export * as ReffuseRuntime from "./ReffuseRuntime.js"
export * as SetStateAction from "./SetStateAction.js"

View File

@@ -1,94 +0,0 @@
import { Array, Function, Option, Predicate } from "effect"
export type Paths<T> = [] | (
T extends readonly any[] ? ArrayPaths<T> :
T extends object ? ObjectPaths<T> :
never
)
export type ArrayPaths<T extends readonly any[]> = {
[K in keyof T as K extends number ? K : never]:
| [K]
| [K, ...Paths<T[K]>]
} extends infer O
? O[keyof O]
: never
export type ObjectPaths<T extends object> = {
[K in keyof T as K extends string | number | symbol ? K : never]:
| [K]
| [K, ...Paths<T[K]>]
} extends infer O
? O[keyof O]
: never
export type ValueFromPath<T, P extends any[]> = P extends [infer Head, ...infer Tail]
? Head extends keyof T
? ValueFromPath<T[Head], Tail>
: T extends readonly any[]
? Head extends number
? ValueFromPath<T[number], Tail>
: never
: never
: T
export type AnyKey = string | number | symbol
export type AnyPath = readonly AnyKey[]
export const unsafeGet: {
<T, const P extends Paths<T>>(path: P): (self: T) => ValueFromPath<T, P>
<T, const P extends Paths<T>>(self: T, path: P): ValueFromPath<T, P>
} = Function.dual(2, <T, const P extends Paths<T>>(self: T, path: P): ValueFromPath<T, P> =>
path.reduce((acc: any, key: any) => acc?.[key], self)
)
export const get: {
<T, const P extends Paths<T>>(path: P): (self: T) => Option.Option<ValueFromPath<T, P>>
<T, const P extends Paths<T>>(self: T, path: P): Option.Option<ValueFromPath<T, P>>
} = Function.dual(2, <T, const P extends Paths<T>>(self: T, path: P): Option.Option<ValueFromPath<T, P>> =>
path.reduce(
(acc: Option.Option<any>, key: any): Option.Option<any> => Option.isSome(acc)
? Predicate.hasProperty(acc.value, key)
? Option.some(acc.value[key])
: Option.none()
: acc,
Option.some(self),
)
)
export const immutableSet: {
<T, const P extends Paths<T>>(path: P, value: ValueFromPath<T, P>): (self: T) => ValueFromPath<T, P>
<T, const P extends Paths<T>>(self: T, path: P, value: ValueFromPath<T, P>): Option.Option<T>
} = Function.dual(3, <T, const P extends Paths<T>>(self: T, path: P, value: ValueFromPath<T, P>): Option.Option<T> => {
const key = Array.head(path as AnyPath)
if (Option.isNone(key))
return Option.some(value as T)
if (!Predicate.hasProperty(self, key.value))
return Option.none()
const child = immutableSet<any, any>(self[key.value], Option.getOrThrow(Array.tail(path as AnyPath)), value)
if (Option.isNone(child))
return child
if (Array.isArray(self))
return typeof key.value === "number"
? Option.some([
...self.slice(0, key.value),
child.value,
...self.slice(key.value + 1),
] as T)
: Option.none()
if (typeof self === "object")
return Option.some(
Object.assign(
Object.create(Object.getPrototypeOf(self)),
{ ...self, [key.value]: child.value },
)
)
return Option.none()
})

View File

@@ -1,100 +0,0 @@
import { Effect, Effectable, Option, Readable, Ref, Stream, Subscribable, SubscriptionRef, SynchronizedRef, type Types, type Unify } from "effect"
import * as PropertyPath from "./PropertyPath.js"
export const SubscriptionSubRefTypeId: unique symbol = Symbol.for("reffuse/types/SubscriptionSubRef")
export type SubscriptionSubRefTypeId = typeof SubscriptionSubRefTypeId
export interface SubscriptionSubRef<in out A, in out B> extends SubscriptionSubRef.Variance<A, B>, SubscriptionRef.SubscriptionRef<A> {
readonly parent: SubscriptionRef.SubscriptionRef<B>
readonly [Unify.typeSymbol]?: unknown
readonly [Unify.unifySymbol]?: SubscriptionSubRefUnify<this>
readonly [Unify.ignoreSymbol]?: SubscriptionSubRefUnifyIgnore
}
export declare namespace SubscriptionSubRef {
export interface Variance<in out A, in out B> {
readonly [SubscriptionSubRefTypeId]: {
readonly _A: Types.Invariant<A>
readonly _B: Types.Invariant<B>
}
}
}
export interface SubscriptionSubRefUnify<A extends { [Unify.typeSymbol]?: any }> extends SubscriptionRef.SubscriptionRefUnify<A> {
SubscriptionSubRef?: () => Extract<A[Unify.typeSymbol], SubscriptionSubRef<any, any>>
}
export interface SubscriptionSubRefUnifyIgnore extends SubscriptionRef.SubscriptionRefUnifyIgnore {
SubscriptionRef?: true
}
const refVariance = { _A: (_: any) => _ }
const synchronizedRefVariance = { _A: (_: any) => _ }
const subscriptionRefVariance = { _A: (_: any) => _ }
const subscriptionSubRefVariance = { _A: (_: any) => _, _B: (_: any) => _ }
class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> implements SubscriptionSubRef<A, B> {
readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId
readonly [Ref.RefTypeId] = refVariance
readonly [SynchronizedRef.SynchronizedRefTypeId] = synchronizedRefVariance
readonly [SubscriptionRef.SubscriptionRefTypeId] = subscriptionRefVariance
readonly [SubscriptionSubRefTypeId] = subscriptionSubRefVariance
readonly get: Effect.Effect<A>
constructor(
readonly parent: SubscriptionRef.SubscriptionRef<B>,
readonly getter: (parentValue: B) => A,
readonly setter: (parentValue: B, value: A) => B,
) {
super()
this.get = Ref.get(this.parent).pipe(Effect.map(this.getter))
}
commit() {
return this.get
}
get changes(): Stream.Stream<A> {
return this.get.pipe(
Effect.map(a => this.parent.changes.pipe(
Stream.map(this.getter),
s => Stream.concat(Stream.make(a), s),
)),
Stream.unwrap,
)
}
modify<C>(f: (a: A) => readonly [C, A]): Effect.Effect<C> {
return this.modifyEffect(a => Effect.succeed(f(a)))
}
modifyEffect<C, E, R>(f: (a: A) => Effect.Effect<readonly [C, A], E, R>): Effect.Effect<C, E, R> {
return Effect.Do.pipe(
Effect.bind("b", () => Ref.get(this.parent)),
Effect.bind("ca", ({ b }) => f(this.getter(b))),
Effect.tap(({ b, ca: [, a] }) => Ref.set(this.parent, this.setter(b, a))),
Effect.map(({ ca: [c] }) => c),
)
}
}
export const makeFromGetSet = <A, B>(
parent: SubscriptionRef.SubscriptionRef<B>,
getter: (parentValue: B) => A,
setter: (parentValue: B, value: A) => B,
): SubscriptionSubRef<A, B> => new SubscriptionSubRefImpl(parent, getter, setter)
export const makeFromPath = <B, const P extends PropertyPath.Paths<B>>(
parent: SubscriptionRef.SubscriptionRef<B>,
path: P,
): SubscriptionSubRef<PropertyPath.ValueFromPath<B, P>, B> => new SubscriptionSubRefImpl(
parent,
parentValue => Option.getOrThrow(PropertyPath.get(parentValue, path)),
(parentValue, value) => Option.getOrThrow(PropertyPath.immutableSet(parentValue, path, value)),
)

View File

@@ -1,3 +0,0 @@
export * as PropertyPath from "./PropertyPath.js"
export * as SetStateAction from "./SetStateAction.js"
export * as SubscriptionSubRef from "./SubscriptionSubRef.js"