@dxos/react-client 0.8.4-main.3f58842 → 0.8.4-main.406dc2a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.mts +11 -0
- package/.storybook/preview.mts +8 -0
- package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
- package/dist/lib/browser/{chunk-O5SEVDJG.mjs → chunk-LO3TU5CK.mjs} +5 -5
- package/dist/lib/browser/chunk-LO3TU5CK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-AAR7V3KL.mjs → chunk-TA2HGRAF.mjs} +64 -67
- package/dist/lib/browser/chunk-TA2HGRAF.mjs.map +7 -0
- package/dist/lib/browser/devtools/index.mjs +2 -2
- package/dist/lib/browser/devtools/index.mjs.map +3 -3
- package/dist/lib/browser/echo/index.mjs +22 -22
- package/dist/lib/browser/echo/index.mjs.map +3 -3
- package/dist/lib/browser/halo/index.mjs +21 -6
- package/dist/lib/browser/halo/index.mjs.map +3 -3
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/invitations/index.mjs +1 -1
- package/dist/lib/browser/mesh/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +51 -50
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-TU2JJLZK.mjs → chunk-AQJH2UNZ.mjs} +5 -5
- package/dist/lib/node-esm/chunk-AQJH2UNZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ZTD6HPV2.mjs → chunk-ZJMNF7GC.mjs} +64 -67
- package/dist/lib/node-esm/chunk-ZJMNF7GC.mjs.map +7 -0
- package/dist/lib/node-esm/devtools/index.mjs +2 -2
- package/dist/lib/node-esm/devtools/index.mjs.map +3 -3
- package/dist/lib/node-esm/echo/index.mjs +22 -22
- package/dist/lib/node-esm/echo/index.mjs.map +3 -3
- package/dist/lib/node-esm/halo/index.mjs +21 -6
- package/dist/lib/node-esm/halo/index.mjs.map +3 -3
- package/dist/lib/node-esm/index.mjs +1 -1
- package/dist/lib/node-esm/invitations/index.mjs +1 -1
- package/dist/lib/node-esm/mesh/index.mjs +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +51 -50
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/client/AgentHostingProvider.d.ts.map +1 -1
- package/dist/types/src/client/ClientProvider.d.ts.map +1 -1
- package/dist/types/src/echo/useQuery.d.ts +3 -3
- package/dist/types/src/echo/useQuery.d.ts.map +1 -1
- package/dist/types/src/echo/useSchema.d.ts +1 -1
- package/dist/types/src/echo/useSchema.d.ts.map +1 -1
- package/dist/types/src/echo/useSpaceInvitations.d.ts.map +1 -1
- package/dist/types/src/echo/useSpaces.d.ts.map +1 -1
- package/dist/types/src/echo/useSubscription.d.ts +1 -1
- package/dist/types/src/echo/useSubscription.d.ts.map +1 -1
- package/dist/types/src/echo/useSyncState.d.ts +1 -1
- package/dist/types/src/echo/useSyncState.d.ts.map +1 -1
- package/dist/types/src/halo/Passkey.stories.d.ts +5 -5
- package/dist/types/src/halo/Passkey.stories.d.ts.map +1 -1
- package/dist/types/src/halo/useHaloInvitations.d.ts.map +1 -1
- package/dist/types/src/invitations/useInvitationStatus.d.ts +1 -1
- package/dist/types/src/invitations/useInvitationStatus.d.ts.map +1 -1
- package/dist/types/src/testing/ClientRepeater.d.ts +2 -2
- package/dist/types/src/testing/ClientRepeater.d.ts.map +1 -1
- package/dist/types/src/testing/ClientRepeater.stories.d.ts +6 -10
- package/dist/types/src/testing/ClientRepeater.stories.d.ts.map +1 -1
- package/dist/types/src/testing/withClientProvider.d.ts +6 -7
- package/dist/types/src/testing/withClientProvider.d.ts.map +1 -1
- package/dist/types/src/testing/withClientProvider.stories.d.ts +7 -9
- package/dist/types/src/testing/withClientProvider.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/moon.yml +4 -0
- package/package.json +38 -31
- package/src/client/AgentHostingProvider.tsx +1 -1
- package/src/client/ClientProvider.test.tsx +3 -2
- package/src/client/ClientProvider.tsx +33 -36
- package/src/client/useConfig.test.tsx +2 -1
- package/src/devtools/useStream.ts +1 -1
- package/src/echo/useQuery.test.tsx +9 -8
- package/src/echo/useQuery.ts +28 -12
- package/src/echo/useSchema.ts +2 -2
- package/src/echo/useSpaceInvitations.ts +2 -1
- package/src/echo/useSpaces.test.tsx +2 -1
- package/src/echo/useSpaces.ts +5 -9
- package/src/echo/useSubscription.ts +1 -1
- package/src/echo/useSyncState.ts +1 -1
- package/src/halo/Passkey.stories.tsx +16 -13
- package/src/halo/useDevices.test.tsx +2 -1
- package/src/halo/useHaloInvitations.ts +1 -1
- package/src/invitations/useInvitationStatus.ts +9 -8
- package/src/testing/ClientRepeater.stories.tsx +12 -8
- package/src/testing/ClientRepeater.tsx +23 -27
- package/src/testing/withClientProvider.stories.tsx +25 -16
- package/src/testing/withClientProvider.tsx +24 -21
- package/tsconfig.json +0 -3
- package/vitest.config.ts +12 -16
- package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
- package/dist/lib/browser/chunk-AAR7V3KL.mjs.map +0 -7
- package/dist/lib/browser/chunk-O5SEVDJG.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TU2JJLZK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZTD6HPV2.mjs.map +0 -7
package/moon.yml
CHANGED
|
@@ -6,6 +6,7 @@ tags:
|
|
|
6
6
|
- ts-test
|
|
7
7
|
- typedoc
|
|
8
8
|
- pack
|
|
9
|
+
- storybook
|
|
9
10
|
tasks:
|
|
10
11
|
compile:
|
|
11
12
|
args:
|
|
@@ -17,3 +18,6 @@ tasks:
|
|
|
17
18
|
- '--entryPoint=src/mesh/index.ts'
|
|
18
19
|
- '--entryPoint=src/testing/index.ts'
|
|
19
20
|
- '--entryPoint=src/worker.ts'
|
|
21
|
+
test:
|
|
22
|
+
inputs:
|
|
23
|
+
- .storybook/*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-client",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.406dc2a",
|
|
4
4
|
"description": "React client API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,41 +10,49 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
"./devtools": {
|
|
13
|
+
"source": "./src/devtools/index.ts",
|
|
13
14
|
"types": "./dist/types/src/devtools/index.d.ts",
|
|
14
15
|
"browser": "./dist/lib/browser/devtools/index.mjs",
|
|
15
16
|
"node": "./dist/lib/node-esm/devtools/index.mjs"
|
|
16
17
|
},
|
|
17
18
|
"./echo": {
|
|
19
|
+
"source": "./src/echo/index.ts",
|
|
18
20
|
"types": "./dist/types/src/echo/index.d.ts",
|
|
19
21
|
"browser": "./dist/lib/browser/echo/index.mjs",
|
|
20
22
|
"node": "./dist/lib/node-esm/echo/index.mjs"
|
|
21
23
|
},
|
|
22
24
|
"./halo": {
|
|
25
|
+
"source": "./src/halo/index.ts",
|
|
23
26
|
"types": "./dist/types/src/halo/index.d.ts",
|
|
24
27
|
"browser": "./dist/lib/browser/halo/index.mjs",
|
|
25
28
|
"node": "./dist/lib/node-esm/halo/index.mjs"
|
|
26
29
|
},
|
|
27
30
|
".": {
|
|
31
|
+
"source": "./src/index.ts",
|
|
28
32
|
"types": "./dist/types/src/index.d.ts",
|
|
29
33
|
"browser": "./dist/lib/browser/index.mjs",
|
|
30
34
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
31
35
|
},
|
|
32
36
|
"./invitations": {
|
|
37
|
+
"source": "./src/invitations/index.ts",
|
|
33
38
|
"types": "./dist/types/src/invitations/index.d.ts",
|
|
34
39
|
"browser": "./dist/lib/browser/invitations/index.mjs",
|
|
35
40
|
"node": "./dist/lib/node-esm/invitations/index.mjs"
|
|
36
41
|
},
|
|
37
42
|
"./mesh": {
|
|
43
|
+
"source": "./src/mesh/index.ts",
|
|
38
44
|
"types": "./dist/types/src/mesh/index.d.ts",
|
|
39
45
|
"browser": "./dist/lib/browser/mesh/index.mjs",
|
|
40
46
|
"node": "./dist/lib/node-esm/mesh/index.mjs"
|
|
41
47
|
},
|
|
42
48
|
"./testing": {
|
|
49
|
+
"source": "./src/testing/index.ts",
|
|
43
50
|
"types": "./dist/types/src/testing/index.d.ts",
|
|
44
51
|
"browser": "./dist/lib/browser/testing/index.mjs",
|
|
45
52
|
"node": "./dist/lib/node-esm/testing/index.mjs"
|
|
46
53
|
},
|
|
47
54
|
"./worker": {
|
|
55
|
+
"source": "./src/worker.ts",
|
|
48
56
|
"types": "./dist/types/src/worker.d.ts",
|
|
49
57
|
"browser": "./dist/lib/browser/worker.mjs",
|
|
50
58
|
"node": "./dist/lib/node-esm/worker.mjs"
|
|
@@ -78,43 +86,42 @@
|
|
|
78
86
|
},
|
|
79
87
|
"dependencies": {
|
|
80
88
|
"react-error-boundary": "^4.0.13",
|
|
81
|
-
"@dxos/async": "0.8.4-main.
|
|
82
|
-
"@dxos/client": "0.8.4-main.
|
|
83
|
-
"@dxos/codec-protobuf": "0.8.4-main.
|
|
84
|
-
"@dxos/config": "0.8.4-main.
|
|
85
|
-
"@dxos/
|
|
86
|
-
"@dxos/
|
|
87
|
-
"@dxos/echo": "0.8.4-main.
|
|
88
|
-
"@dxos/
|
|
89
|
-
"@dxos/
|
|
90
|
-
"@dxos/
|
|
91
|
-
"@dxos/
|
|
92
|
-
"@dxos/
|
|
93
|
-
"@dxos/
|
|
94
|
-
"@dxos/
|
|
95
|
-
"@dxos/util": "0.8.4-main.3f58842"
|
|
89
|
+
"@dxos/async": "0.8.4-main.406dc2a",
|
|
90
|
+
"@dxos/client": "0.8.4-main.406dc2a",
|
|
91
|
+
"@dxos/codec-protobuf": "0.8.4-main.406dc2a",
|
|
92
|
+
"@dxos/config": "0.8.4-main.406dc2a",
|
|
93
|
+
"@dxos/debug": "0.8.4-main.406dc2a",
|
|
94
|
+
"@dxos/echo": "0.8.4-main.406dc2a",
|
|
95
|
+
"@dxos/echo-signals": "0.8.4-main.406dc2a",
|
|
96
|
+
"@dxos/context": "0.8.4-main.406dc2a",
|
|
97
|
+
"@dxos/log": "0.8.4-main.406dc2a",
|
|
98
|
+
"@dxos/protocols": "0.8.4-main.406dc2a",
|
|
99
|
+
"@dxos/react-hooks": "0.8.4-main.406dc2a",
|
|
100
|
+
"@dxos/node-std": "0.8.4-main.406dc2a",
|
|
101
|
+
"@dxos/invariant": "0.8.4-main.406dc2a",
|
|
102
|
+
"@dxos/util": "0.8.4-main.406dc2a"
|
|
96
103
|
},
|
|
97
104
|
"devDependencies": {
|
|
98
|
-
"@types/react": "~
|
|
99
|
-
"@types/react-dom": "~
|
|
100
|
-
"react": "~
|
|
101
|
-
"react-dom": "~
|
|
105
|
+
"@types/react": "~19.2.2",
|
|
106
|
+
"@types/react-dom": "~19.2.1",
|
|
107
|
+
"react": "~19.2.0",
|
|
108
|
+
"react-dom": "~19.2.0",
|
|
102
109
|
"typedoc": "0.28.1",
|
|
103
|
-
"@dxos/
|
|
104
|
-
"@dxos/
|
|
105
|
-
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.
|
|
106
|
-
"@dxos/
|
|
107
|
-
"@dxos/
|
|
108
|
-
"@dxos/test-utils": "0.8.4-main.
|
|
110
|
+
"@dxos/react-ui": "0.8.4-main.406dc2a",
|
|
111
|
+
"@dxos/random": "0.8.4-main.406dc2a",
|
|
112
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.406dc2a",
|
|
113
|
+
"@dxos/react-ui-theme": "0.8.4-main.406dc2a",
|
|
114
|
+
"@dxos/storybook-utils": "0.8.4-main.406dc2a",
|
|
115
|
+
"@dxos/test-utils": "0.8.4-main.406dc2a"
|
|
109
116
|
},
|
|
110
117
|
"peerDependencies": {
|
|
111
|
-
"react": "
|
|
112
|
-
"react-dom": "
|
|
118
|
+
"react": "^19.0.0",
|
|
119
|
+
"react-dom": "^19.0.0"
|
|
113
120
|
},
|
|
114
121
|
"optionalDependencies": {
|
|
115
|
-
"@dxos/random": "0.8.4-main.
|
|
116
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
117
|
-
"@dxos/react-ui
|
|
122
|
+
"@dxos/random": "0.8.4-main.406dc2a",
|
|
123
|
+
"@dxos/react-ui-theme": "0.8.4-main.406dc2a",
|
|
124
|
+
"@dxos/react-ui": "0.8.4-main.406dc2a"
|
|
118
125
|
},
|
|
119
126
|
"publishConfig": {
|
|
120
127
|
"access": "public"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, {
|
|
5
|
+
import React, { type PropsWithChildren, createContext, useContext, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type AgentHostingProviderClient, AgentManagerClient, FakeAgentHostingProvider } from '@dxos/client';
|
|
8
8
|
import { type Halo } from '@dxos/client/halo';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2020 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { act, cleanup, render, renderHook, screen } from '@testing-library/react';
|
|
6
6
|
import React, { Component, type PropsWithChildren } from 'react';
|
|
7
7
|
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
8
8
|
|
|
@@ -10,9 +10,10 @@ import { waitForCondition } from '@dxos/async';
|
|
|
10
10
|
import { Client, Config, SystemStatus, fromHost } from '@dxos/client';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
|
|
13
|
+
import { useIdentity } from '../halo';
|
|
14
|
+
|
|
13
15
|
import { ClientProvider } from './ClientProvider';
|
|
14
16
|
import { useClient } from './useClient';
|
|
15
|
-
import { useIdentity } from '../halo';
|
|
16
17
|
|
|
17
18
|
log.config({ filter: 'ClientContext:debug,warn' });
|
|
18
19
|
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import React, {
|
|
6
|
-
forwardRef,
|
|
7
6
|
type FunctionComponent,
|
|
8
7
|
type PropsWithChildren,
|
|
8
|
+
forwardRef,
|
|
9
9
|
useEffect,
|
|
10
10
|
useImperativeHandle,
|
|
11
11
|
useState,
|
|
@@ -15,12 +15,13 @@ import { Client, type ClientOptions, type ClientServicesProvider, SystemStatus }
|
|
|
15
15
|
import { type Config } from '@dxos/config';
|
|
16
16
|
import { registerSignalsRuntime } from '@dxos/echo-signals/react';
|
|
17
17
|
import { log } from '@dxos/log';
|
|
18
|
-
import { useControlledState } from '@dxos/react-hooks';
|
|
19
|
-
import {
|
|
18
|
+
import { useAsyncEffect, useControlledState } from '@dxos/react-hooks';
|
|
19
|
+
import { type MaybePromise, type Provider, getAsyncProviderValue } from '@dxos/util';
|
|
20
20
|
|
|
21
|
-
import { ClientContext, type ClientContextProps } from './context';
|
|
22
21
|
import { printBanner } from '../banner';
|
|
23
22
|
|
|
23
|
+
import { ClientContext, type ClientContextProps } from './context';
|
|
24
|
+
|
|
24
25
|
/**
|
|
25
26
|
* Properties for the ClientProvider.
|
|
26
27
|
*/
|
|
@@ -80,10 +81,10 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
80
81
|
(
|
|
81
82
|
{
|
|
82
83
|
children,
|
|
83
|
-
config:
|
|
84
|
-
client:
|
|
85
|
-
services:
|
|
86
|
-
status:
|
|
84
|
+
config: configParam,
|
|
85
|
+
client: clientParam,
|
|
86
|
+
services: servicesParam,
|
|
87
|
+
status: statusParam,
|
|
87
88
|
fallback: Fallback = () => null,
|
|
88
89
|
signalsRuntime = true,
|
|
89
90
|
noBanner,
|
|
@@ -108,13 +109,13 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
108
109
|
throw error;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
const [client, setClient] = useState(
|
|
112
|
+
const [client, setClient] = useState(clientParam instanceof Client ? clientParam : undefined);
|
|
112
113
|
|
|
113
114
|
// Provide external access.
|
|
114
115
|
useImperativeHandle(forwardedRef, () => client, [client]);
|
|
115
116
|
|
|
116
117
|
// Client status subscription.
|
|
117
|
-
const [status, setStatus] = useControlledState(
|
|
118
|
+
const [status, setStatus] = useControlledState(statusParam);
|
|
118
119
|
useEffect(() => {
|
|
119
120
|
if (!client) {
|
|
120
121
|
return;
|
|
@@ -125,7 +126,7 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
125
126
|
}, [client]);
|
|
126
127
|
|
|
127
128
|
// Create and/or initialize client.
|
|
128
|
-
|
|
129
|
+
useAsyncEffect(async () => {
|
|
129
130
|
let disposed = false;
|
|
130
131
|
const initialize = async (client: Client) => {
|
|
131
132
|
if (!client.initialized) {
|
|
@@ -140,42 +141,38 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
setClient(client);
|
|
143
|
-
|
|
144
144
|
if (!noBanner) {
|
|
145
145
|
printBanner(client);
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
let client: Client;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await initialize(client);
|
|
165
|
-
}
|
|
166
|
-
} catch (err) {
|
|
167
|
-
if (!disposed) {
|
|
168
|
-
log.catch(err);
|
|
169
|
-
}
|
|
150
|
+
try {
|
|
151
|
+
if (clientParam) {
|
|
152
|
+
// Asynchronously request client.
|
|
153
|
+
client = await getAsyncProviderValue(clientParam);
|
|
154
|
+
await initialize(client);
|
|
155
|
+
} else {
|
|
156
|
+
// Asynchronously construct client (config may be undefined).
|
|
157
|
+
const config = await getAsyncProviderValue(configParam);
|
|
158
|
+
log('resolved config', { config });
|
|
159
|
+
const services = await getAsyncProviderValue(servicesParam, config);
|
|
160
|
+
log('created services', { services });
|
|
161
|
+
client = new Client({ config, services, ...options });
|
|
162
|
+
log('created client');
|
|
163
|
+
await initialize(client);
|
|
170
164
|
}
|
|
171
|
-
})
|
|
165
|
+
} catch (err) {
|
|
166
|
+
if (!disposed) {
|
|
167
|
+
log.catch(err);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
172
170
|
|
|
173
171
|
return () => {
|
|
174
172
|
log('clean up');
|
|
175
173
|
disposed = true;
|
|
176
|
-
clearTimeout(t);
|
|
177
174
|
// Only destroy if the client is not provided by the parent.
|
|
178
|
-
if (!
|
|
175
|
+
if (!clientParam) {
|
|
179
176
|
void client
|
|
180
177
|
?.destroy()
|
|
181
178
|
.then(() => {
|
|
@@ -184,7 +181,7 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
184
181
|
.catch((err) => log.catch(err));
|
|
185
182
|
}
|
|
186
183
|
};
|
|
187
|
-
}, [
|
|
184
|
+
}, [configParam, clientParam, servicesParam, noBanner]);
|
|
188
185
|
|
|
189
186
|
if (!client?.initialized || status !== SystemStatus.ACTIVE) {
|
|
190
187
|
return <Fallback client={client} status={status} />;
|
|
@@ -8,9 +8,10 @@ import { describe, expect, test } from 'vitest';
|
|
|
8
8
|
import { waitForCondition } from '@dxos/async';
|
|
9
9
|
import { Config, SystemStatus } from '@dxos/client';
|
|
10
10
|
|
|
11
|
-
import { useConfig } from './useConfig';
|
|
12
11
|
import { createClient, createClientContextProvider } from '../testing/util';
|
|
13
12
|
|
|
13
|
+
import { useConfig } from './useConfig';
|
|
14
|
+
|
|
14
15
|
// TODO(burdon): Disabled in CI since flaky.
|
|
15
16
|
describe.runIf(!process.env.CI)('Config hook', () => {
|
|
16
17
|
const render = () => useConfig();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type DependencyList,
|
|
5
|
+
import { type DependencyList, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type Stream } from '@dxos/codec-protobuf/stream';
|
|
8
8
|
import { log } from '@dxos/log';
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
import { renderHook } from '@testing-library/react';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
|
|
8
|
-
import { Expando, Filter
|
|
8
|
+
import { Expando, Filter } from '@dxos/client/echo';
|
|
9
|
+
import { Obj, Type } from '@dxos/echo';
|
|
9
10
|
|
|
10
|
-
import { useQuery } from './useQuery';
|
|
11
11
|
import { createClient, createClientContextProvider } from '../testing/util';
|
|
12
12
|
|
|
13
|
+
import { useQuery } from './useQuery';
|
|
14
|
+
|
|
13
15
|
describe('useQuery', () => {
|
|
14
16
|
// TODO(dmaretskyi): Fix this test.
|
|
15
17
|
test.skip('deleting an element should result in correct render sequence', async () => {
|
|
@@ -18,9 +20,9 @@ describe('useQuery', () => {
|
|
|
18
20
|
const wrapper = await createClientContextProvider(client);
|
|
19
21
|
|
|
20
22
|
// Create 3 test objects: Alice, Bob, Charlie.
|
|
21
|
-
const alice =
|
|
22
|
-
const bob =
|
|
23
|
-
const charlie =
|
|
23
|
+
const alice = Obj.make(Type.Expando, { name: 'Alice' });
|
|
24
|
+
const bob = Obj.make(Type.Expando, { name: 'Bob' });
|
|
25
|
+
const charlie = Obj.make(Type.Expando, { name: 'Charlie' });
|
|
24
26
|
|
|
25
27
|
space!.db.add(alice);
|
|
26
28
|
space!.db.add(bob);
|
|
@@ -64,7 +66,7 @@ describe('useQuery', () => {
|
|
|
64
66
|
* Actual: 4 renders
|
|
65
67
|
* 1. [] (empty)
|
|
66
68
|
* 2. ['Alice', 'Bob', 'Charlie'] (all loaded)
|
|
67
|
-
* 3. ['Alice', 'Charlie', 'Bob'] (FLASH BUG - Bob moves to end!)
|
|
69
|
+
* 3. ['Alice', 'Charlie', 'Bob'] (FLASH BUG - Bob moves to end!)x
|
|
68
70
|
* 4. ['Alice', 'Charlie'] (Bob finally removed)
|
|
69
71
|
*/
|
|
70
72
|
|
|
@@ -81,7 +83,7 @@ describe('useQuery', () => {
|
|
|
81
83
|
const wrapper = await createClientContextProvider(client);
|
|
82
84
|
|
|
83
85
|
// Create 10 test objects: 1, 2, 3, ..., 10.
|
|
84
|
-
const objects = Array.from({ length: 10 }, (_, i) =>
|
|
86
|
+
const objects = Array.from({ length: 10 }, (_, i) => Obj.make(Type.Expando, { value: i + 1 }));
|
|
85
87
|
|
|
86
88
|
objects.forEach((obj) => space!.db.add(obj));
|
|
87
89
|
await space!.db.flush();
|
|
@@ -121,7 +123,6 @@ describe('useQuery', () => {
|
|
|
121
123
|
new Set([]), // Initial loading state.
|
|
122
124
|
new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), // All objects loaded.
|
|
123
125
|
// TODO(dmaretskyi): Fix this with query ordering.
|
|
124
|
-
new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), // Getting another render for some reason.
|
|
125
126
|
new Set([]), // All items deleted.
|
|
126
127
|
]);
|
|
127
128
|
});
|
package/src/echo/useQuery.ts
CHANGED
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
import { useMemo, useSyncExternalStore } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type Echo,
|
|
9
|
+
Filter,
|
|
10
|
+
type Live,
|
|
11
|
+
Query,
|
|
12
|
+
type Queryable,
|
|
13
|
+
type Queue,
|
|
14
|
+
type Space,
|
|
15
|
+
isSpace,
|
|
16
|
+
} from '@dxos/client/echo';
|
|
8
17
|
|
|
9
18
|
const EMPTY_ARRAY: never[] = [];
|
|
10
19
|
|
|
@@ -12,30 +21,37 @@ const noop = () => {};
|
|
|
12
21
|
|
|
13
22
|
// TODO(dmaretskyi): Queries are fully serializable, so we can remove `deps` argument.
|
|
14
23
|
interface UseQueryFn {
|
|
15
|
-
<Q extends Query.Any>(
|
|
24
|
+
<Q extends Query.Any>(
|
|
25
|
+
spaceOrEcho: Space | Echo | Queue<any> | undefined,
|
|
26
|
+
query: Q,
|
|
27
|
+
deps?: any[],
|
|
28
|
+
): Live<Query.Type<Q>>[];
|
|
16
29
|
|
|
17
|
-
<F extends Filter.Any>(
|
|
30
|
+
<F extends Filter.Any>(
|
|
31
|
+
spaceOrEcho: Space | Echo | Queue<any> | undefined,
|
|
32
|
+
filter: F,
|
|
33
|
+
deps?: any[],
|
|
34
|
+
): Live<Filter.Type<F>>[];
|
|
18
35
|
}
|
|
19
36
|
|
|
20
37
|
/**
|
|
21
38
|
* Create subscription.
|
|
22
39
|
*/
|
|
23
40
|
export const useQuery: UseQueryFn = (
|
|
24
|
-
|
|
41
|
+
// TODO(burdon): Remove Space and just requre Queryable?
|
|
42
|
+
resource: Space | Queryable | undefined,
|
|
25
43
|
queryOrFilter: Query.Any | Filter.Any,
|
|
26
44
|
deps?: any[],
|
|
27
45
|
): Live<unknown>[] => {
|
|
28
46
|
const query = Filter.is(queryOrFilter) ? Query.select(queryOrFilter) : queryOrFilter;
|
|
29
47
|
|
|
30
48
|
const { getObjects, subscribe } = useMemo(() => {
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: isSpace(spaceOrEcho)
|
|
36
|
-
? spaceOrEcho.db.query(query)
|
|
37
|
-
: spaceOrEcho.query(query);
|
|
49
|
+
let queryResult = undefined;
|
|
50
|
+
if (resource) {
|
|
51
|
+
queryResult = isSpace(resource) ? resource.db.query(query) : resource.query(query);
|
|
52
|
+
}
|
|
38
53
|
|
|
54
|
+
let subscribed = false;
|
|
39
55
|
return {
|
|
40
56
|
getObjects: () => (subscribed && queryResult ? queryResult.objects : EMPTY_ARRAY),
|
|
41
57
|
subscribe: (cb: () => void) => {
|
|
@@ -47,7 +63,7 @@ export const useQuery: UseQueryFn = (
|
|
|
47
63
|
};
|
|
48
64
|
},
|
|
49
65
|
};
|
|
50
|
-
}, [
|
|
66
|
+
}, [resource, JSON.stringify(query.ast), ...(deps ?? [])]);
|
|
51
67
|
|
|
52
68
|
// https://beta.reactjs.org/reference/react/useSyncExternalStore
|
|
53
69
|
// NOTE: This hook will resubscribe whenever the callback passed to the first argument changes; make sure it is stable.
|
package/src/echo/useSchema.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as Schema from 'effect/Schema';
|
|
6
6
|
import { useMemo, useSyncExternalStore } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type Client } from '@dxos/client';
|
|
9
9
|
import { type Space } from '@dxos/client/echo';
|
|
10
|
-
import { type BaseSchema } from '@dxos/echo
|
|
10
|
+
import { type BaseSchema } from '@dxos/echo/internal';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Subscribe to and retrieve schema changes from a space's schema registry.
|
|
@@ -8,9 +8,10 @@ import { MulticastObservable } from '@dxos/async';
|
|
|
8
8
|
import { type PublicKey } from '@dxos/client';
|
|
9
9
|
import { useMulticastObservable } from '@dxos/react-hooks';
|
|
10
10
|
|
|
11
|
-
import { useSpace } from './useSpaces';
|
|
12
11
|
import { type CancellableInvitationObservable, useInvitationStatus } from '../invitations';
|
|
13
12
|
|
|
13
|
+
import { useSpace } from './useSpaces';
|
|
14
|
+
|
|
14
15
|
export const useSpaceInvitations = (spaceKey?: PublicKey): CancellableInvitationObservable[] => {
|
|
15
16
|
const space = useSpace(spaceKey);
|
|
16
17
|
return useMulticastObservable(space?.invitations ?? MulticastObservable.empty()) ?? [];
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import { act, renderHook } from '@testing-library/react';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
|
|
8
|
-
import { useSpace, useSpaces } from './useSpaces';
|
|
9
8
|
import { createClient, createClientContextProvider } from '../testing/util';
|
|
10
9
|
|
|
10
|
+
import { useSpace, useSpaces } from './useSpaces';
|
|
11
|
+
|
|
11
12
|
describe('useSpaces', () => {
|
|
12
13
|
test('lists existing spaces', async () => {
|
|
13
14
|
const { client } = await createClient({ createIdentity: true });
|
package/src/echo/useSpaces.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2020 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type PublicKeyLike } from '@dxos/client';
|
|
8
8
|
import { type Space, SpaceState } from '@dxos/client/echo';
|
|
9
|
-
import { useMulticastObservable } from '@dxos/react-hooks';
|
|
9
|
+
import { useAsyncEffect, useMulticastObservable } from '@dxos/react-hooks';
|
|
10
10
|
|
|
11
11
|
import { useClient } from '../client';
|
|
12
12
|
|
|
@@ -23,18 +23,14 @@ export const useSpace = (spaceKeyLike?: PublicKeyLike): Space | undefined => {
|
|
|
23
23
|
const spaces = useMulticastObservable<Space[]>(client.spaces);
|
|
24
24
|
const [ready, setReady] = useState(false);
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
useAsyncEffect(async () => {
|
|
27
27
|
// Only wait for ready if looking for the default space.
|
|
28
28
|
if (spaceKeyLike) {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setReady(true);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return () => clearTimeout(timeout);
|
|
32
|
+
await client.spaces.waitUntilReady();
|
|
33
|
+
setReady(true);
|
|
38
34
|
}, [client, spaceKeyLike]);
|
|
39
35
|
|
|
40
36
|
if (spaceKeyLike) {
|
|
@@ -18,7 +18,7 @@ export const useSubscription = (cb: () => void, selection: Selection) => {
|
|
|
18
18
|
const callbackRef = useRef(cb);
|
|
19
19
|
callbackRef.current = cb;
|
|
20
20
|
|
|
21
|
-
const subscriptionRef = useRef<SubscriptionHandle>();
|
|
21
|
+
const subscriptionRef = useRef<SubscriptionHandle>(null);
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
subscriptionRef.current = createSubscription(() => {
|
package/src/echo/useSyncState.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { type PeerSyncState, type
|
|
7
|
+
import { type PeerSyncState, type Space, type SpaceSyncStateMap } from '@dxos/client/echo';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { type SpaceId } from '@dxos/keys';
|
|
10
10
|
import { EdgeService } from '@dxos/protocols';
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
6
|
import React, { useCallback } from 'react';
|
|
8
7
|
|
|
9
8
|
import { Config, PublicKey } from '@dxos/client';
|
|
10
9
|
import { invariant } from '@dxos/invariant';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
12
11
|
import { Button } from '@dxos/react-ui';
|
|
12
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
13
13
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
14
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
15
14
|
|
|
16
|
-
import { useCredentials } from './useCredentials';
|
|
17
|
-
import { useIdentity } from './useIdentity';
|
|
18
15
|
import { useClient } from '../client';
|
|
19
16
|
import { withClientProvider } from '../testing';
|
|
20
17
|
|
|
18
|
+
import { useCredentials } from './useCredentials';
|
|
19
|
+
import { useIdentity } from './useIdentity';
|
|
20
|
+
|
|
21
21
|
const getNewChallenge = () => Math.random().toString(36).substring(2);
|
|
22
22
|
|
|
23
23
|
const Test = () => {
|
|
@@ -43,7 +43,7 @@ const Test = () => {
|
|
|
43
43
|
challenge: new TextEncoder().encode(challenge),
|
|
44
44
|
rp: { id: location.hostname, name: 'Test' },
|
|
45
45
|
user: {
|
|
46
|
-
id: lookupKey.asUint8Array()
|
|
46
|
+
id: lookupKey.asUint8Array() as Uint8Array<ArrayBuffer>,
|
|
47
47
|
name: identity.did,
|
|
48
48
|
displayName: identity.profile?.displayName ?? '',
|
|
49
49
|
},
|
|
@@ -125,11 +125,6 @@ const Test = () => {
|
|
|
125
125
|
);
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
export default {
|
|
129
|
-
title: 'sdk/react-client/Passkeys',
|
|
130
|
-
render: Test,
|
|
131
|
-
};
|
|
132
|
-
|
|
133
128
|
const config = new Config({
|
|
134
129
|
runtime: {
|
|
135
130
|
client: {
|
|
@@ -150,6 +145,14 @@ const config = new Config({
|
|
|
150
145
|
},
|
|
151
146
|
});
|
|
152
147
|
|
|
153
|
-
|
|
148
|
+
const meta = {
|
|
149
|
+
title: 'sdk/react-client/Passkeys',
|
|
150
|
+
render: Test,
|
|
154
151
|
decorators: [withClientProvider({ config }), withTheme],
|
|
155
|
-
};
|
|
152
|
+
} satisfies Meta;
|
|
153
|
+
|
|
154
|
+
export default meta;
|
|
155
|
+
|
|
156
|
+
type Story = StoryObj<typeof meta>;
|
|
157
|
+
|
|
158
|
+
export const Default: Story = {};
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import { renderHook } from '@testing-library/react';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
|
|
8
|
-
import { useDevices } from './useDevices';
|
|
9
8
|
import { createClient, createClientContextProvider } from '../testing/util';
|
|
10
9
|
|
|
10
|
+
import { useDevices } from './useDevices';
|
|
11
|
+
|
|
11
12
|
describe('useDevices', () => {
|
|
12
13
|
test('lists existing devices', async () => {
|
|
13
14
|
const { client } = await createClient({ createIdentity: true });
|
|
@@ -7,7 +7,7 @@ import { useMemo } from 'react';
|
|
|
7
7
|
import { useMulticastObservable } from '@dxos/react-hooks';
|
|
8
8
|
|
|
9
9
|
import { useClient } from '../client';
|
|
10
|
-
import {
|
|
10
|
+
import { type CancellableInvitationObservable, useInvitationStatus } from '../invitations';
|
|
11
11
|
|
|
12
12
|
export const useHaloInvitations = (): CancellableInvitationObservable[] => {
|
|
13
13
|
const client = useClient();
|