@dxos/react-client 0.8.4-main.fffef41 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.storybook/main.mts +2 -4
  2. package/.storybook/preview.mts +2 -2
  3. package/LICENSE +102 -5
  4. package/README.md +1 -1
  5. package/dist/lib/browser/chunk-3LVU7RNK.mjs +16 -0
  6. package/dist/lib/browser/chunk-3LVU7RNK.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-CZMIVAGI.mjs +8 -0
  8. package/dist/lib/browser/chunk-CZMIVAGI.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-XT352YI6.mjs +134 -0
  10. package/dist/lib/browser/chunk-XT352YI6.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-LO3TU5CK.mjs → chunk-YHE6WD44.mjs} +3 -13
  12. package/dist/lib/browser/{chunk-LO3TU5CK.mjs.map → chunk-YHE6WD44.mjs.map} +2 -2
  13. package/dist/lib/browser/devtools/index.mjs +3 -7
  14. package/dist/lib/browser/devtools/index.mjs.map +2 -2
  15. package/dist/lib/browser/echo/index.mjs +125 -176
  16. package/dist/lib/browser/echo/index.mjs.map +4 -4
  17. package/dist/lib/browser/halo/index.mjs +3 -2
  18. package/dist/lib/browser/halo/index.mjs.map +2 -2
  19. package/dist/lib/browser/index.mjs +99 -12
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/invitations/index.mjs +1 -1
  22. package/dist/lib/browser/mesh/index.mjs +2 -1
  23. package/dist/lib/browser/mesh/index.mjs.map +1 -1
  24. package/dist/lib/browser/meta.json +1 -1
  25. package/dist/lib/browser/testing/index.mjs +75 -119
  26. package/dist/lib/browser/testing/index.mjs.map +3 -3
  27. package/dist/lib/node-esm/chunk-CUDKNAMV.mjs +17 -0
  28. package/dist/lib/node-esm/chunk-CUDKNAMV.mjs.map +7 -0
  29. package/dist/lib/node-esm/{chunk-AQJH2UNZ.mjs → chunk-RQJPEHDY.mjs} +3 -13
  30. package/dist/lib/node-esm/{chunk-AQJH2UNZ.mjs.map → chunk-RQJPEHDY.mjs.map} +2 -2
  31. package/dist/lib/node-esm/chunk-WL3Z5HOH.mjs +135 -0
  32. package/dist/lib/node-esm/chunk-WL3Z5HOH.mjs.map +7 -0
  33. package/dist/lib/node-esm/chunk-WUTK2IJF.mjs +10 -0
  34. package/dist/lib/node-esm/chunk-WUTK2IJF.mjs.map +7 -0
  35. package/dist/lib/node-esm/devtools/index.mjs +3 -7
  36. package/dist/lib/node-esm/devtools/index.mjs.map +2 -2
  37. package/dist/lib/node-esm/echo/index.mjs +125 -176
  38. package/dist/lib/node-esm/echo/index.mjs.map +4 -4
  39. package/dist/lib/node-esm/halo/index.mjs +3 -2
  40. package/dist/lib/node-esm/halo/index.mjs.map +2 -2
  41. package/dist/lib/node-esm/index.mjs +99 -12
  42. package/dist/lib/node-esm/index.mjs.map +4 -4
  43. package/dist/lib/node-esm/invitations/index.mjs +1 -1
  44. package/dist/lib/node-esm/mesh/index.mjs +2 -1
  45. package/dist/lib/node-esm/mesh/index.mjs.map +1 -1
  46. package/dist/lib/node-esm/meta.json +1 -1
  47. package/dist/lib/node-esm/testing/index.mjs +75 -119
  48. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  49. package/dist/types/src/banner.d.ts.map +1 -1
  50. package/dist/types/src/client/AgentHostingProvider.d.ts.map +1 -1
  51. package/dist/types/src/client/ClientProvider.d.ts +1 -11
  52. package/dist/types/src/client/ClientProvider.d.ts.map +1 -1
  53. package/dist/types/src/client/useClientStatus.d.ts.map +1 -1
  54. package/dist/types/src/devtools/useStream.d.ts.map +1 -1
  55. package/dist/types/src/echo/index.d.ts +4 -3
  56. package/dist/types/src/echo/index.d.ts.map +1 -1
  57. package/dist/types/src/echo/useFeedSyncState.d.ts +13 -0
  58. package/dist/types/src/echo/useFeedSyncState.d.ts.map +1 -0
  59. package/dist/types/src/echo/useMembers.d.ts +2 -2
  60. package/dist/types/src/echo/useMembers.d.ts.map +1 -1
  61. package/dist/types/src/echo/useRegistry.d.ts +6 -0
  62. package/dist/types/src/echo/useRegistry.d.ts.map +1 -0
  63. package/dist/types/src/echo/useSpaceInvitations.d.ts +3 -2
  64. package/dist/types/src/echo/useSpaceInvitations.d.ts.map +1 -1
  65. package/dist/types/src/echo/useSpaceProperties.d.ts +13 -0
  66. package/dist/types/src/echo/useSpaceProperties.d.ts.map +1 -0
  67. package/dist/types/src/echo/useSpaces.d.ts +19 -8
  68. package/dist/types/src/echo/useSpaces.d.ts.map +1 -1
  69. package/dist/types/src/echo/useSubscription.d.ts.map +1 -1
  70. package/dist/types/src/echo/useSyncState.d.ts.map +1 -1
  71. package/dist/types/src/halo/Passkey.stories.d.ts.map +1 -1
  72. package/dist/types/src/halo/useHaloInvitations.d.ts.map +1 -1
  73. package/dist/types/src/halo/useKeyStore.d.ts.map +1 -1
  74. package/dist/types/src/invitations/useInvitationStatus.d.ts.map +1 -1
  75. package/dist/types/src/testing/ClientRepeater.d.ts +5 -4
  76. package/dist/types/src/testing/ClientRepeater.d.ts.map +1 -1
  77. package/dist/types/src/testing/ClientRepeater.stories.d.ts.map +1 -1
  78. package/dist/types/src/testing/context.d.ts +4 -1
  79. package/dist/types/src/testing/context.d.ts.map +1 -1
  80. package/dist/types/src/testing/util.d.ts.map +1 -1
  81. package/dist/types/src/testing/withClientProvider.d.ts +0 -3
  82. package/dist/types/src/testing/withClientProvider.d.ts.map +1 -1
  83. package/dist/types/src/testing/withClientProvider.stories.d.ts +2 -1
  84. package/dist/types/src/testing/withClientProvider.stories.d.ts.map +1 -1
  85. package/dist/types/tsconfig.tsbuildinfo +1 -1
  86. package/docs/README.md +38 -38
  87. package/moon.yml +2 -5
  88. package/package.json +37 -58
  89. package/src/client/ClientProvider.test.tsx +0 -1
  90. package/src/client/ClientProvider.tsx +12 -27
  91. package/src/client/useConfig.test.tsx +0 -1
  92. package/src/echo/index.ts +4 -3
  93. package/src/echo/useFeedSyncState.ts +78 -0
  94. package/src/echo/useMembers.ts +5 -3
  95. package/src/echo/useRegistry.ts +15 -0
  96. package/src/echo/useSpaceInvitations.ts +9 -5
  97. package/src/echo/useSpaceProperties.ts +28 -0
  98. package/src/echo/useSpaces.test.tsx +7 -14
  99. package/src/echo/useSpaces.ts +33 -26
  100. package/src/echo/useSyncState.ts +3 -7
  101. package/src/halo/Passkey.stories.tsx +5 -8
  102. package/src/halo/useDevices.test.tsx +0 -1
  103. package/src/testing/ClientRepeater.stories.tsx +11 -9
  104. package/src/testing/ClientRepeater.tsx +11 -15
  105. package/src/testing/context.tsx +4 -2
  106. package/src/testing/util.tsx +0 -1
  107. package/src/testing/withClientProvider.stories.tsx +15 -10
  108. package/src/testing/withClientProvider.tsx +62 -81
  109. package/tsconfig.json +7 -4
  110. package/typedoc.json +1 -1
  111. package/vitest.config.ts +1 -3
  112. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  113. package/dist/lib/browser/chunk-TA2HGRAF.mjs +0 -309
  114. package/dist/lib/browser/chunk-TA2HGRAF.mjs.map +0 -7
  115. package/dist/lib/node-esm/chunk-ZJMNF7GC.mjs +0 -311
  116. package/dist/lib/node-esm/chunk-ZJMNF7GC.mjs.map +0 -7
  117. package/dist/types/src/echo/useQuery.d.ts +0 -11
  118. package/dist/types/src/echo/useQuery.d.ts.map +0 -1
  119. package/dist/types/src/echo/useQuery.test.d.ts +0 -2
  120. package/dist/types/src/echo/useQuery.test.d.ts.map +0 -1
  121. package/dist/types/src/echo/useQueue.d.ts +0 -11
  122. package/dist/types/src/echo/useQueue.d.ts.map +0 -1
  123. package/dist/types/src/echo/useSchema.d.ts +0 -8
  124. package/dist/types/src/echo/useSchema.d.ts.map +0 -1
  125. package/dist/types/src/playwright/playwright.config.d.ts +0 -3
  126. package/dist/types/src/playwright/playwright.config.d.ts.map +0 -1
  127. package/dist/types/src/playwright/smoke.spec.d.ts +0 -2
  128. package/dist/types/src/playwright/smoke.spec.d.ts.map +0 -1
  129. package/src/echo/useQuery.test.tsx +0 -129
  130. package/src/echo/useQuery.ts +0 -64
  131. package/src/echo/useQueue.ts +0 -74
  132. package/src/echo/useSchema.ts +0 -54
  133. package/src/playwright/playwright.config.ts +0 -17
  134. package/src/playwright/smoke.spec.ts +0 -24
package/docs/README.md CHANGED
@@ -168,41 +168,41 @@ dxos/react-client --> dxos/react-async
168
168
 
169
169
  ## Dependencies
170
170
 
171
- | Module | Direct |
172
- |---|---|
173
- | [`@dxos/async`](../../../common/async/docs/README.md) | ✓ |
174
- | [`@dxos/broadcast`](../../../core/mesh/broadcast/docs/README.md) | |
175
- | [`@dxos/client`](../../client/docs/README.md) | ✓ |
176
- | [`@dxos/client-services`](../../client-services/docs/README.md) | ✓ |
177
- | [`@dxos/codec-protobuf`](../../../common/codec-protobuf/docs/README.md) | ✓ |
178
- | [`@dxos/config`](../../config/docs/README.md) | ✓ |
179
- | [`@dxos/context`](../../../common/context/docs/README.md) | |
180
- | [`@dxos/credentials`](../../../core/halo/credentials/docs/README.md) | |
181
- | [`@dxos/crypto`](../../../common/crypto/docs/README.md) | |
182
- | [`@dxos/debug`](../../../common/debug/docs/README.md) | ✓ |
183
- | [`@dxos/echo-db`](../../../core/echo/echo-db/docs/README.md) | |
184
- | [`@dxos/errors`](../../errors/docs/README.md) | |
185
- | [`@dxos/feed-store`](../../../common/feed-store/docs/README.md) | |
186
- | [`@dxos/hypercore`](../../../common/hypercore/docs/README.md) | |
187
- | [`@dxos/keyring`](../../../core/halo/keyring/docs/README.md) | |
188
- | [`@dxos/keys`](../../../common/keys/docs/README.md) | ✓ |
189
- | [`@dxos/log`](../../../common/log/docs/README.md) | ✓ |
190
- | [`@dxos/mesh-protocol`](../../../core/mesh/mesh-protocol/docs/README.md) | |
191
- | [`@dxos/messaging`](../../../core/mesh/messaging/docs/README.md) | ✓ |
192
- | [`@dxos/model-factory`](../../../core/echo/model-factory/docs/README.md) | |
193
- | [`@dxos/network-generator`](../../../core/mesh/network-generator/docs/README.md) | |
194
- | [`@dxos/network-manager`](../../../core/mesh/network-manager/docs/README.md) | |
195
- | [`@dxos/document-model`](../../../core/echo/document-model/docs/README.md) | |
196
- | [`@dxos/protocol-plugin-presence`](../../../core/mesh/protocol-plugin-presence/docs/README.md) | |
197
- | [`@dxos/protocol-plugin-replicator`](../../../core/mesh/protocol-plugin-replicator/docs/README.md) | |
198
- | [`@dxos/protocol-plugin-rpc`](../../../core/mesh/protocol-plugin-rpc/docs/README.md) | |
199
- | [`@dxos/protocols`](../../../core/protocols/docs/README.md) | ✓ |
200
- | [`@dxos/random-access-storage`](../../../common/random-access-storage/docs/README.md) | |
201
- | [`@dxos/react-async`](../../../common/react-async/docs/README.md) | ✓ |
202
- | [`@dxos/rpc`](../../../core/mesh/rpc/docs/README.md) | ✓ |
203
- | [`@dxos/rpc-tunnel`](../../../core/mesh/rpc-tunnel/docs/README.md) | ✓ |
204
- | [`@dxos/teleport`](../../../core/mesh/teleport/docs/README.md) | |
205
- | [`@dxos/teleport-plugin-replicator`](../../../core/mesh/teleport-plugin-replicator/docs/README.md) | |
206
- | [`@dxos/text-model`](../../../core/echo/text-model/docs/README.md) | |
207
- | [`@dxos/timeframe`](../../../common/timeframe/docs/README.md) | |
208
- | [`@dxos/util`](../../../common/util/docs/README.md) | ✓ |
171
+ | Module | Direct |
172
+ | -------------------------------------------------------------------------------------------------- | ------- |
173
+ | [`@dxos/async`](../../../common/async/docs/README.md) | ✓ |
174
+ | [`@dxos/broadcast`](../../../core/mesh/broadcast/docs/README.md) | |
175
+ | [`@dxos/client`](../../client/docs/README.md) | ✓ |
176
+ | [`@dxos/client-services`](../../client-services/docs/README.md) | ✓ |
177
+ | [`@dxos/codec-protobuf`](../../../common/codec-protobuf/docs/README.md) | ✓ |
178
+ | [`@dxos/config`](../../config/docs/README.md) | ✓ |
179
+ | [`@dxos/context`](../../../common/context/docs/README.md) | |
180
+ | [`@dxos/credentials`](../../../core/halo/credentials/docs/README.md) | |
181
+ | [`@dxos/crypto`](../../../common/crypto/docs/README.md) | |
182
+ | [`@dxos/debug`](../../../common/debug/docs/README.md) | ✓ |
183
+ | [`@dxos/echo-db`](../../../core/echo/echo-db/docs/README.md) | |
184
+ | [`@dxos/errors`](../../errors/docs/README.md) | |
185
+ | [`@dxos/feed-store`](../../../common/feed-store/docs/README.md) | |
186
+ | [`@dxos/hypercore`](../../../common/hypercore/docs/README.md) | |
187
+ | [`@dxos/keyring`](../../../core/halo/keyring/docs/README.md) | |
188
+ | [`@dxos/keys`](../../../common/keys/docs/README.md) | ✓ |
189
+ | [`@dxos/log`](../../../common/log/docs/README.md) | ✓ |
190
+ | [`@dxos/mesh-protocol`](../../../core/mesh/mesh-protocol/docs/README.md) | |
191
+ | [`@dxos/messaging`](../../../core/mesh/messaging/docs/README.md) | ✓ |
192
+ | [`@dxos/model-factory`](../../../core/echo/model-factory/docs/README.md) | |
193
+ | [`@dxos/network-generator`](../../../core/mesh/network-generator/docs/README.md) | |
194
+ | [`@dxos/network-manager`](../../../core/mesh/network-manager/docs/README.md) | |
195
+ | [`@dxos/document-model`](../../../core/echo/document-model/docs/README.md) | |
196
+ | [`@dxos/protocol-plugin-presence`](../../../core/mesh/protocol-plugin-presence/docs/README.md) | |
197
+ | [`@dxos/protocol-plugin-replicator`](../../../core/mesh/protocol-plugin-replicator/docs/README.md) | |
198
+ | [`@dxos/protocol-plugin-rpc`](../../../core/mesh/protocol-plugin-rpc/docs/README.md) | |
199
+ | [`@dxos/protocols`](../../../core/protocols/docs/README.md) | ✓ |
200
+ | [`@dxos/random-access-storage`](../../../common/random-access-storage/docs/README.md) | |
201
+ | [`@dxos/react-async`](../../../common/react-async/docs/README.md) | ✓ |
202
+ | [`@dxos/rpc`](../../../core/mesh/rpc/docs/README.md) | ✓ |
203
+ | [`@dxos/rpc-tunnel`](../../../core/mesh/rpc-tunnel/docs/README.md) | ✓ |
204
+ | [`@dxos/teleport`](../../../core/mesh/teleport/docs/README.md) | |
205
+ | [`@dxos/teleport-plugin-replicator`](../../../core/mesh/teleport-plugin-replicator/docs/README.md) | |
206
+ | [`@dxos/text-model`](../../../core/echo/text-model/docs/README.md) | |
207
+ | [`@dxos/timeframe`](../../../common/timeframe/docs/README.md) | |
208
+ | [`@dxos/util`](../../../common/util/docs/README.md) | ✓ |
package/moon.yml CHANGED
@@ -1,9 +1,9 @@
1
- type: library
1
+ layer: library
2
2
  language: typescript
3
3
  tags:
4
- - e2e
5
4
  - ts-build
6
5
  - ts-test
6
+ - ts-test-storybook
7
7
  - typedoc
8
8
  - pack
9
9
  - storybook
@@ -18,6 +18,3 @@ tasks:
18
18
  - '--entryPoint=src/mesh/index.ts'
19
19
  - '--entryPoint=src/testing/index.ts'
20
20
  - '--entryPoint=src/worker.ts'
21
- test:
22
- inputs:
23
- - .storybook/*
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@dxos/react-client",
3
- "version": "0.8.4-main.fffef41",
3
+ "version": "0.9.0",
4
4
  "description": "React client API",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
- "sideEffects": true,
13
+ "sideEffects": false,
10
14
  "type": "module",
11
15
  "exports": {
12
16
  "./devtools": {
@@ -59,69 +63,44 @@
59
63
  }
60
64
  },
61
65
  "types": "dist/types/src/index.d.ts",
62
- "typesVersions": {
63
- "*": {
64
- "devtools": [
65
- "dist/types/src/devtools/index.d.ts"
66
- ],
67
- "echo": [
68
- "dist/types/src/echo/index.d.ts"
69
- ],
70
- "halo": [
71
- "dist/types/src/halo/index.d.ts"
72
- ],
73
- "invitations": [
74
- "dist/types/src/invitations/index.d.ts"
75
- ],
76
- "mesh": [
77
- "dist/types/src/mesh/index.d.ts"
78
- ],
79
- "testing": [
80
- "dist/types/src/testing/index.d.ts"
81
- ],
82
- "worker": [
83
- "dist/types/src/worker.d.ts"
84
- ]
85
- }
86
- },
87
66
  "dependencies": {
88
- "react-error-boundary": "^4.0.13",
89
- "@dxos/async": "0.8.4-main.fffef41",
90
- "@dxos/client": "0.8.4-main.fffef41",
91
- "@dxos/context": "0.8.4-main.fffef41",
92
- "@dxos/codec-protobuf": "0.8.4-main.fffef41",
93
- "@dxos/debug": "0.8.4-main.fffef41",
94
- "@dxos/config": "0.8.4-main.fffef41",
95
- "@dxos/echo": "0.8.4-main.fffef41",
96
- "@dxos/echo-signals": "0.8.4-main.fffef41",
97
- "@dxos/invariant": "0.8.4-main.fffef41",
98
- "@dxos/log": "0.8.4-main.fffef41",
99
- "@dxos/node-std": "0.8.4-main.fffef41",
100
- "@dxos/protocols": "0.8.4-main.fffef41",
101
- "@dxos/react-hooks": "0.8.4-main.fffef41",
102
- "@dxos/util": "0.8.4-main.fffef41"
67
+ "@dxos/async": "0.9.0",
68
+ "@dxos/codec-protobuf": "0.9.0",
69
+ "@dxos/config": "0.9.0",
70
+ "@dxos/context": "0.9.0",
71
+ "@dxos/client": "0.9.0",
72
+ "@dxos/debug": "0.9.0",
73
+ "@dxos/echo-protocol": "0.9.0",
74
+ "@dxos/echo-react": "0.9.0",
75
+ "@dxos/invariant": "0.9.0",
76
+ "@dxos/echo": "0.9.0",
77
+ "@dxos/node-std": "0.9.0",
78
+ "@dxos/log": "0.9.0",
79
+ "@dxos/react-hooks": "0.9.0",
80
+ "@dxos/keys": "0.9.0",
81
+ "@dxos/util": "0.9.0"
103
82
  },
104
83
  "devDependencies": {
105
- "@types/react": "~19.2.2",
106
- "@types/react-dom": "~19.2.2",
107
- "react": "~19.2.0",
108
- "react-dom": "~19.2.0",
84
+ "@types/react": "~19.2.7",
85
+ "@types/react-dom": "~19.2.3",
86
+ "react": "~19.2.3",
87
+ "react-dom": "~19.2.3",
109
88
  "typedoc": "0.28.1",
110
- "@dxos/random": "0.8.4-main.fffef41",
111
- "@dxos/react-ui": "0.8.4-main.fffef41",
112
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.fffef41",
113
- "@dxos/react-ui-theme": "0.8.4-main.fffef41",
114
- "@dxos/storybook-utils": "0.8.4-main.fffef41",
115
- "@dxos/test-utils": "0.8.4-main.fffef41"
89
+ "@dxos/random": "0.9.0",
90
+ "@dxos/react-ui": "0.9.0",
91
+ "@dxos/react-ui-syntax-highlighter": "0.9.0",
92
+ "@dxos/test-utils": "0.9.0",
93
+ "@dxos/ui-theme": "0.9.0",
94
+ "@dxos/storybook-utils": "0.9.0"
116
95
  },
117
96
  "peerDependencies": {
118
- "react": "^19.0.0",
119
- "react-dom": "^19.0.0"
97
+ "react": "~19.2.3",
98
+ "react-dom": "~19.2.3"
120
99
  },
121
100
  "optionalDependencies": {
122
- "@dxos/random": "0.8.4-main.fffef41",
123
- "@dxos/react-ui-theme": "0.8.4-main.fffef41",
124
- "@dxos/react-ui": "0.8.4-main.fffef41"
101
+ "@dxos/random": "0.9.0",
102
+ "@dxos/ui-theme": "0.9.0",
103
+ "@dxos/react-ui": "0.9.0"
125
104
  },
126
105
  "publishConfig": {
127
106
  "access": "public"
@@ -11,7 +11,6 @@ import { Client, Config, SystemStatus, fromHost } from '@dxos/client';
11
11
  import { log } from '@dxos/log';
12
12
 
13
13
  import { useIdentity } from '../halo';
14
-
15
14
  import { ClientProvider } from './ClientProvider';
16
15
  import { useClient } from './useClient';
17
16
 
@@ -13,13 +13,11 @@ import React, {
13
13
 
14
14
  import { Client, type ClientOptions, type ClientServicesProvider, SystemStatus } from '@dxos/client';
15
15
  import { type Config } from '@dxos/config';
16
- import { registerSignalsRuntime } from '@dxos/echo-signals/react';
17
16
  import { log } from '@dxos/log';
18
17
  import { useAsyncEffect, useControlledState } from '@dxos/react-hooks';
19
18
  import { type MaybePromise, type Provider, getAsyncProviderValue } from '@dxos/util';
20
19
 
21
20
  import { printBanner } from '../banner';
22
-
23
21
  import { ClientContext, type ClientContextProps } from './context';
24
22
 
25
23
  /**
@@ -56,12 +54,6 @@ export type ClientProviderProps = Omit<ClientOptions, 'config' | 'services'> &
56
54
  */
57
55
  fallback?: FunctionComponent<Partial<ClientContextProps>>;
58
56
 
59
- /**
60
- * Enable (by default) registration of Preact signals runtime for reactive ECHO objects.
61
- * @see https://www.npmjs.com/package/@preact/signals-react
62
- */
63
- signalsRuntime?: boolean;
64
-
65
57
  /**
66
58
  * Skip the DXOS banner.
67
59
  */
@@ -81,24 +73,17 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
81
73
  (
82
74
  {
83
75
  children,
84
- config: configParam,
85
- client: clientParam,
86
- services: servicesParam,
87
- status: statusParam,
76
+ config: configProp,
77
+ client: clientProp,
78
+ services: servicesProp,
79
+ status: statusProp,
88
80
  fallback: Fallback = () => null,
89
- signalsRuntime = true,
90
81
  noBanner,
91
82
  onInitialized,
92
83
  ...options
93
84
  },
94
85
  forwardedRef,
95
86
  ) => {
96
- useEffect(() => {
97
- // TODO(wittjosiah): Ideally this should be imported asynchronously because it is optional.
98
- // Unfortunately, async import seemed to break signals React instrumentation.
99
- signalsRuntime && registerSignalsRuntime();
100
- }, []);
101
-
102
87
  // The client is initialized asynchronously.
103
88
  // If an error occurs during initialization, it is caught and the state is set.
104
89
  // This allows the error to be thrown in the render method.
@@ -109,13 +94,13 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
109
94
  throw error;
110
95
  }
111
96
 
112
- const [client, setClient] = useState(clientParam instanceof Client ? clientParam : undefined);
97
+ const [client, setClient] = useState(clientProp instanceof Client ? clientProp : undefined);
113
98
 
114
99
  // Provide external access.
115
100
  useImperativeHandle(forwardedRef, () => client, [client]);
116
101
 
117
102
  // Client status subscription.
118
- const [status, setStatus] = useControlledState(statusParam);
103
+ const [status, setStatus] = useControlledState(statusProp);
119
104
  useEffect(() => {
120
105
  if (!client) {
121
106
  return;
@@ -148,15 +133,15 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
148
133
 
149
134
  let client: Client;
150
135
  try {
151
- if (clientParam) {
136
+ if (clientProp) {
152
137
  // Asynchronously request client.
153
- client = await getAsyncProviderValue(clientParam);
138
+ client = await getAsyncProviderValue(clientProp);
154
139
  await initialize(client);
155
140
  } else {
156
141
  // Asynchronously construct client (config may be undefined).
157
- const config = await getAsyncProviderValue(configParam);
142
+ const config = await getAsyncProviderValue(configProp);
158
143
  log('resolved config', { config });
159
- const services = await getAsyncProviderValue(servicesParam, config);
144
+ const services = await getAsyncProviderValue(servicesProp, config);
160
145
  log('created services', { services });
161
146
  client = new Client({ config, services, ...options });
162
147
  log('created client');
@@ -172,7 +157,7 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
172
157
  log('clean up');
173
158
  disposed = true;
174
159
  // Only destroy if the client is not provided by the parent.
175
- if (!clientParam) {
160
+ if (!clientProp) {
176
161
  void client
177
162
  ?.destroy()
178
163
  .then(() => {
@@ -181,7 +166,7 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
181
166
  .catch((err) => log.catch(err));
182
167
  }
183
168
  };
184
- }, [configParam, clientParam, servicesParam, noBanner]);
169
+ }, [configProp, clientProp, servicesProp, noBanner]);
185
170
 
186
171
  if (!client?.initialized || status !== SystemStatus.ACTIVE) {
187
172
  return <Fallback client={client} status={status} />;
@@ -9,7 +9,6 @@ import { waitForCondition } from '@dxos/async';
9
9
  import { Config, SystemStatus } from '@dxos/client';
10
10
 
11
11
  import { createClient, createClientContextProvider } from '../testing/util';
12
-
13
12
  import { useConfig } from './useConfig';
14
13
 
15
14
  // TODO(burdon): Disabled in CI since flaky.
package/src/echo/index.ts CHANGED
@@ -3,12 +3,13 @@
3
3
  //
4
4
 
5
5
  export * from '@dxos/client/echo';
6
+ export * from '@dxos/echo-react';
6
7
 
7
8
  export * from './useMembers';
8
- export * from './useQuery';
9
- export * from './useQueue';
10
- export * from './useSchema';
11
9
  export * from './useSpaces';
12
10
  export * from './useSpaceInvitations';
11
+ export * from './useSpaceProperties';
13
12
  export * from './useSubscription';
14
13
  export * from './useSyncState';
14
+ export * from './useFeedSyncState';
15
+ export * from './useRegistry';
@@ -0,0 +1,78 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { useEffect, useState } from 'react';
6
+
7
+ import { type SpaceId } from '@dxos/keys';
8
+
9
+ import { useClient } from '../client';
10
+
11
+ const DEFAULT_POLL_INTERVAL_MS = 5_000;
12
+
13
+ export type FeedSyncState = {
14
+ /** Combined blocks to pull + push across namespaces. */
15
+ pending: number;
16
+ /** Total blocks stored locally across namespaces. */
17
+ total: number;
18
+ };
19
+
20
+ export type FeedSyncStateMap = Record<SpaceId, FeedSyncState>;
21
+
22
+ /**
23
+ * Polls queue replication state per space.
24
+ */
25
+ export const useFeedSyncState = (pollIntervalMs = DEFAULT_POLL_INTERVAL_MS): FeedSyncStateMap => {
26
+ const client = useClient();
27
+ const [feedSyncState, setFeedSyncState] = useState<FeedSyncStateMap>({});
28
+
29
+ useEffect(() => {
30
+ const queueService = client.services.services.QueueService;
31
+ if (!queueService) {
32
+ return;
33
+ }
34
+
35
+ let cancelled = false;
36
+
37
+ const poll = async () => {
38
+ const spaces = client.spaces.get();
39
+ const entries = await Promise.all(
40
+ spaces.map(async (space) => {
41
+ try {
42
+ const response = await queueService.getSyncState({ spaceId: space.id });
43
+ const state = (response.namespaces ?? []).reduce<FeedSyncState>(
44
+ (acc, entry) => {
45
+ acc.pending += Number(entry.blocksToPull ?? 0) + Number(entry.blocksToPush ?? 0);
46
+ acc.total += Number(entry.totalBlocks ?? 0);
47
+ return acc;
48
+ },
49
+ { pending: 0, total: 0 },
50
+ );
51
+ return [space.id, state] as const;
52
+ } catch {
53
+ return [space.id, { pending: 0, total: 0 }] as const;
54
+ }
55
+ }),
56
+ );
57
+
58
+ if (!cancelled) {
59
+ setFeedSyncState(Object.fromEntries(entries));
60
+ }
61
+ };
62
+
63
+ void poll();
64
+ const interval = setInterval(() => void poll(), pollIntervalMs);
65
+
66
+ const spacesSubscription = client.spaces.subscribe(() => {
67
+ void poll();
68
+ });
69
+
70
+ return () => {
71
+ cancelled = true;
72
+ clearInterval(interval);
73
+ spacesSubscription.unsubscribe();
74
+ };
75
+ }, [client, pollIntervalMs]);
76
+
77
+ return feedSyncState;
78
+ };
@@ -3,16 +3,18 @@
3
3
  //
4
4
 
5
5
  import { MulticastObservable } from '@dxos/async';
6
- import { type PublicKey } from '@dxos/client';
6
+ import { PublicKey, type PublicKeyLike } from '@dxos/client';
7
7
  import { HaloSpaceMember, type SpaceMember } from '@dxos/client/echo';
8
8
  import { useMulticastObservable } from '@dxos/react-hooks';
9
9
 
10
10
  import { useSpaces } from './useSpaces';
11
11
 
12
- export const useMembers = (spaceKey: PublicKey | undefined): SpaceMember[] => {
12
+ export const useMembers = (spaceKey: PublicKeyLike | undefined): SpaceMember[] => {
13
13
  // TODO(dmaretskyi): useSpace hook for spaces that are not ready.
14
14
  const spaces = useSpaces({ all: true });
15
- const space = spaceKey ? spaces.find((space) => space.key.equals(spaceKey)) : undefined;
15
+ const space = spaceKey
16
+ ? spaces.find((space) => (spaceKey instanceof PublicKey ? space.key.equals(spaceKey) : space.id === spaceKey))
17
+ : undefined;
16
18
 
17
19
  // EMPTY_OBSERVABLE needs to be a stable reference to avoid re-subscribing on every render.
18
20
  const members = useMulticastObservable(space?.members ?? MulticastObservable.empty()) ?? [];
@@ -0,0 +1,15 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Registry } from '@dxos/echo';
6
+
7
+ import { useClient } from '../client';
8
+
9
+ /**
10
+ * Returns the hypergraph registry attached to the current client.
11
+ */
12
+ export const useRegistry = (): Registry.Registry => {
13
+ const client = useClient();
14
+ return client.graph.registry;
15
+ };
@@ -6,19 +6,23 @@ import { useMemo } from 'react';
6
6
 
7
7
  import { MulticastObservable } from '@dxos/async';
8
8
  import { type PublicKey } from '@dxos/client';
9
+ import { type SpaceId } from '@dxos/keys';
9
10
  import { useMulticastObservable } from '@dxos/react-hooks';
10
11
 
11
12
  import { type CancellableInvitationObservable, useInvitationStatus } from '../invitations';
12
-
13
13
  import { useSpace } from './useSpaces';
14
14
 
15
- export const useSpaceInvitations = (spaceKey?: PublicKey): CancellableInvitationObservable[] => {
16
- const space = useSpace(spaceKey);
15
+ // TODO(wittjosiah): Currently unable to remove `PublicKey` from this api.
16
+ // When initially joining a space that is all that is returned.
17
+ export const useSpaceInvitations = (spaceId?: SpaceId | PublicKey): CancellableInvitationObservable[] => {
18
+ const space = useSpace(spaceId);
17
19
  return useMulticastObservable(space?.invitations ?? MulticastObservable.empty()) ?? [];
18
20
  };
19
21
 
20
- export const useSpaceInvitation = (spaceKey?: PublicKey, invitationId?: string) => {
21
- const invitations = useSpaceInvitations(spaceKey);
22
+ // TODO(wittjosiah): Currently unable to remove `PublicKey` from this api.
23
+ // When initially joining a space that is all that is returned.
24
+ export const useSpaceInvitation = (spaceId?: SpaceId | PublicKey, invitationId?: string) => {
25
+ const invitations = useSpaceInvitations(spaceId);
22
26
  const invitation = useMemo(
23
27
  () => invitations.find((invitation) => invitation.get().invitationId === invitationId),
24
28
  [invitations],
@@ -0,0 +1,28 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { MulticastObservable } from '@dxos/async';
6
+ import { type SpaceProperties, SpaceState } from '@dxos/client/echo';
7
+ import { type Key, type Obj } from '@dxos/echo';
8
+ import { type ObjectUpdateCallback, useObject } from '@dxos/echo-react';
9
+ import { useMulticastObservable } from '@dxos/react-hooks';
10
+
11
+ import { useSpace } from './useSpaces';
12
+
13
+ /**
14
+ * Subscribe to a space's properties with reactive updates.
15
+ * Returns undefined if the space is undefined or not ready yet.
16
+ * Automatically waits for the space to be ready before returning properties.
17
+ *
18
+ * @param spaceId - The space ID to get properties from (can be undefined).
19
+ * @returns A tuple of [snapshot, updateCallback] or [undefined, no-op] if not ready.
20
+ */
21
+ export const useSpaceProperties = (
22
+ spaceId: Key.SpaceId | undefined,
23
+ ): [Obj.Snapshot<SpaceProperties> | undefined, ObjectUpdateCallback<SpaceProperties>] => {
24
+ const space = useSpace(spaceId);
25
+ const spaceState = useMulticastObservable(space?.state ?? MulticastObservable.empty());
26
+ const properties = spaceState === SpaceState.SPACE_READY ? space?.properties : undefined;
27
+ return useObject(properties);
28
+ };
@@ -6,19 +6,18 @@ import { act, renderHook } from '@testing-library/react';
6
6
  import { describe, expect, test } from 'vitest';
7
7
 
8
8
  import { createClient, createClientContextProvider } from '../testing/util';
9
-
10
9
  import { useSpace, useSpaces } from './useSpaces';
11
10
 
12
11
  describe('useSpaces', () => {
13
12
  test('lists existing spaces', async () => {
14
- const { client } = await createClient({ createIdentity: true });
13
+ const { client } = await createClient({ createIdentity: true, createSpace: true });
15
14
  const wrapper = await createClientContextProvider(client);
16
15
  const { result } = renderHook(() => useSpaces(), { wrapper });
17
16
  expect(result.current.length).to.eq(1);
18
17
  });
19
18
 
20
19
  test('updates when new spaces are created', async () => {
21
- const { client } = await createClient({ createIdentity: true });
20
+ const { client } = await createClient({ createIdentity: true, createSpace: true });
22
21
  const wrapper = await createClientContextProvider(client);
23
22
  const { result, rerender } = renderHook(() => useSpaces(), { wrapper });
24
23
  expect(result.current.length).to.eq(1);
@@ -31,23 +30,17 @@ describe('useSpaces', () => {
31
30
  });
32
31
 
33
32
  describe('useSpace', () => {
34
- test('gets default space', async () => {
35
- const { client } = await createClient();
33
+ test('returns undefined when no id provided', async () => {
34
+ const { client } = await createClient({ createIdentity: true });
36
35
  const wrapper = await createClientContextProvider(client);
37
- const { result, rerender } = renderHook(() => useSpace(), { wrapper });
36
+ const { result } = renderHook(() => useSpace(undefined), { wrapper });
38
37
  expect(result.current).to.be.undefined;
39
- await act(async () => {
40
- await client.halo.createIdentity();
41
- await client.spaces.waitUntilReady();
42
- });
43
- rerender();
44
- expect(result.current).to.not.be.undefined;
45
38
  });
46
39
 
47
- test('gets space by key', async () => {
40
+ test('gets space by id', async () => {
48
41
  const { client, space } = await createClient({ createIdentity: true, createSpace: true });
49
42
  const wrapper = await createClientContextProvider(client);
50
- const { result } = renderHook(() => useSpace(space!.key), { wrapper });
43
+ const { result } = renderHook(() => useSpace(space!.id), { wrapper });
51
44
  expect(result.current).to.not.be.undefined;
52
45
  });
53
46
  });