@dxos/react-client 0.8.4-main.ae835ea → 0.8.4-main.bc674ce
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 +1 -1
- package/.storybook/preview.mts +2 -2
- package/dist/lib/browser/chunk-5UKA2BMA.mjs +179 -0
- package/dist/lib/browser/chunk-5UKA2BMA.mjs.map +7 -0
- package/dist/lib/browser/chunk-PFF63FPR.mjs +16 -0
- package/dist/lib/browser/chunk-PFF63FPR.mjs.map +7 -0
- package/dist/lib/browser/chunk-TSF6Y5VB.mjs +8 -0
- package/dist/lib/browser/chunk-TSF6Y5VB.mjs.map +7 -0
- package/dist/lib/browser/devtools/index.mjs +2 -1
- package/dist/lib/browser/devtools/index.mjs.map +1 -1
- package/dist/lib/browser/echo/index.mjs +44 -94
- package/dist/lib/browser/echo/index.mjs.map +4 -4
- package/dist/lib/browser/halo/index.mjs +2 -1
- package/dist/lib/browser/halo/index.mjs.map +1 -1
- package/dist/lib/browser/index.mjs +114 -12
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/mesh/index.mjs +2 -1
- package/dist/lib/browser/mesh/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +78 -73
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-373DPHEQ.mjs +10 -0
- package/dist/lib/node-esm/chunk-373DPHEQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NETTSER2.mjs +17 -0
- package/dist/lib/node-esm/chunk-NETTSER2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-T3QTQHBD.mjs +180 -0
- package/dist/lib/node-esm/chunk-T3QTQHBD.mjs.map +7 -0
- package/dist/lib/node-esm/devtools/index.mjs +2 -1
- package/dist/lib/node-esm/devtools/index.mjs.map +1 -1
- package/dist/lib/node-esm/echo/index.mjs +44 -94
- package/dist/lib/node-esm/echo/index.mjs.map +4 -4
- package/dist/lib/node-esm/halo/index.mjs +2 -1
- package/dist/lib/node-esm/halo/index.mjs.map +1 -1
- package/dist/lib/node-esm/index.mjs +114 -12
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/mesh/index.mjs +2 -1
- package/dist/lib/node-esm/mesh/index.mjs.map +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +78 -73
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/client/ClientProvider.d.ts +0 -10
- package/dist/types/src/client/ClientProvider.d.ts.map +1 -1
- package/dist/types/src/echo/index.d.ts +2 -2
- package/dist/types/src/echo/index.d.ts.map +1 -1
- package/dist/types/src/echo/useMembers.d.ts +2 -2
- package/dist/types/src/echo/useMembers.d.ts.map +1 -1
- package/dist/types/src/echo/useQueue.d.ts +2 -2
- package/dist/types/src/echo/useQueue.d.ts.map +1 -1
- package/dist/types/src/echo/useSpaceInvitations.d.ts +3 -2
- package/dist/types/src/echo/useSpaceInvitations.d.ts.map +1 -1
- package/dist/types/src/echo/useSpaceProperties.d.ts +13 -0
- package/dist/types/src/echo/useSpaceProperties.d.ts.map +1 -0
- package/dist/types/src/echo/useSpaces.d.ts +17 -8
- package/dist/types/src/echo/useSpaces.d.ts.map +1 -1
- package/dist/types/src/testing/ClientRepeater.d.ts +5 -4
- package/dist/types/src/testing/ClientRepeater.d.ts.map +1 -1
- package/dist/types/src/testing/ClientRepeater.stories.d.ts.map +1 -1
- package/dist/types/src/testing/context.d.ts +4 -2
- package/dist/types/src/testing/context.d.ts.map +1 -1
- package/dist/types/src/testing/withClientProvider.d.ts +0 -3
- package/dist/types/src/testing/withClientProvider.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -31
- package/src/client/ClientProvider.tsx +12 -26
- package/src/echo/index.ts +2 -2
- package/src/echo/useMembers.ts +5 -3
- package/src/echo/useQueue.ts +2 -2
- package/src/echo/useSpaceInvitations.ts +9 -4
- package/src/echo/useSpaceProperties.ts +28 -0
- package/src/echo/useSpaces.test.tsx +1 -1
- package/src/echo/useSpaces.ts +33 -12
- package/src/echo/useSyncState.ts +2 -2
- package/src/playwright/playwright.config.ts +1 -1
- package/src/testing/ClientRepeater.stories.tsx +8 -3
- package/src/testing/ClientRepeater.tsx +9 -12
- package/src/testing/context.tsx +4 -3
- package/src/testing/withClientProvider.tsx +61 -47
- package/tsconfig.json +3 -3
- package/vitest.config.ts +1 -1
- package/dist/lib/browser/chunk-TA2HGRAF.mjs +0 -309
- package/dist/lib/browser/chunk-TA2HGRAF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZJMNF7GC.mjs +0 -311
- package/dist/lib/node-esm/chunk-ZJMNF7GC.mjs.map +0 -7
- package/dist/types/src/echo/useQuery.d.ts +0 -11
- package/dist/types/src/echo/useQuery.d.ts.map +0 -1
- package/dist/types/src/echo/useQuery.test.d.ts +0 -2
- package/dist/types/src/echo/useQuery.test.d.ts.map +0 -1
- package/dist/types/src/echo/useSchema.d.ts +0 -8
- package/dist/types/src/echo/useSchema.d.ts.map +0 -1
- package/src/echo/useQuery.test.tsx +0 -129
- package/src/echo/useQuery.ts +0 -63
- package/src/echo/useSchema.ts +0 -54
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClientProvider
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-5UKA2BMA.mjs";
|
|
4
|
+
import "../chunk-TSF6Y5VB.mjs";
|
|
4
5
|
|
|
5
6
|
// src/testing/index.ts
|
|
6
7
|
export * from "@dxos/client/testing";
|
|
@@ -9,24 +10,20 @@ export * from "@dxos/client/testing";
|
|
|
9
10
|
import { createContext, useContext } from "react";
|
|
10
11
|
import { raise } from "@dxos/debug";
|
|
11
12
|
var ClientStory = /* @__PURE__ */ createContext(void 0);
|
|
12
|
-
var
|
|
13
|
+
var useClientStory = () => {
|
|
13
14
|
return useContext(ClientStory) ?? raise(new Error("Missing ClientStory"));
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
// src/testing/ClientRepeater.tsx
|
|
17
|
-
import React, {
|
|
18
|
+
import React, { useRef, useState } from "react";
|
|
18
19
|
import { Client } from "@dxos/client";
|
|
19
20
|
import { TestBuilder, performInvitation } from "@dxos/client/testing";
|
|
20
|
-
import { registerSignalsRuntime } from "@dxos/echo-signals/react";
|
|
21
21
|
import { faker } from "@dxos/random";
|
|
22
22
|
import { useAsyncEffect } from "@dxos/react-hooks";
|
|
23
23
|
var ClientRepeater = (props) => {
|
|
24
24
|
const { component: Component, controls: Controls, count = 1, types, createIdentity, createSpace, onCreateSpace } = props;
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
registerSignalsRuntime();
|
|
27
|
-
}, []);
|
|
28
25
|
const [clients, setClients] = useState(props.clients ?? []);
|
|
29
|
-
const [
|
|
26
|
+
const [spaceId, setSpaceId] = useState();
|
|
30
27
|
const testBuilder = useRef(new TestBuilder());
|
|
31
28
|
useAsyncEffect(async () => {
|
|
32
29
|
const clients2 = [
|
|
@@ -44,7 +41,7 @@ var ClientRepeater = (props) => {
|
|
|
44
41
|
const space = await client.spaces.create({
|
|
45
42
|
name: faker.commerce.productName()
|
|
46
43
|
});
|
|
47
|
-
|
|
44
|
+
setSpaceId(space.id);
|
|
48
45
|
await onCreateSpace?.({
|
|
49
46
|
client,
|
|
50
47
|
space
|
|
@@ -67,13 +64,13 @@ var ClientRepeater = (props) => {
|
|
|
67
64
|
}, /* @__PURE__ */ React.createElement(Component, {
|
|
68
65
|
id: index,
|
|
69
66
|
count: clients.length,
|
|
70
|
-
|
|
67
|
+
spaceId,
|
|
71
68
|
...props.args
|
|
72
69
|
}))));
|
|
73
70
|
};
|
|
74
71
|
|
|
75
72
|
// src/testing/withClientProvider.tsx
|
|
76
|
-
import React2, {
|
|
73
|
+
import React2, { useCallback, useEffect, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
77
74
|
import { ErrorBoundary as NaturalErrorBoundary } from "react-error-boundary";
|
|
78
75
|
import { Trigger } from "@dxos/async";
|
|
79
76
|
import { TestBuilder as TestBuilder2, performInvitation as performInvitation2 } from "@dxos/client/testing";
|
|
@@ -103,7 +100,8 @@ var initializeClient = async (client, { createIdentity, createSpace, onCreateIde
|
|
|
103
100
|
}, context);
|
|
104
101
|
}
|
|
105
102
|
return {
|
|
106
|
-
space
|
|
103
|
+
space,
|
|
104
|
+
spaceId: space?.id
|
|
107
105
|
};
|
|
108
106
|
};
|
|
109
107
|
var withClientProvider = ({ createIdentity, createSpace, onCreateSpace, onCreateIdentity, onInitialized, ...props } = {}) => {
|
|
@@ -127,83 +125,91 @@ var withClientProvider = ({ createIdentity, createSpace, onCreateSpace, onCreate
|
|
|
127
125
|
}, /* @__PURE__ */ React2.createElement(Story, null))));
|
|
128
126
|
};
|
|
129
127
|
};
|
|
130
|
-
var MultiClientContext = /* @__PURE__ */ createContext2({
|
|
131
|
-
id: 0
|
|
132
|
-
});
|
|
133
|
-
var useMultiClient = () => useContext2(MultiClientContext);
|
|
134
128
|
var withMultiClientProvider = ({ numClients = 2, createIdentity, createSpace, onCreateSpace, onCreateIdentity, onInitialized, ...props }) => {
|
|
135
129
|
return (Story, context) => {
|
|
136
|
-
const builder = useRef2(new TestBuilder2());
|
|
137
|
-
const hostRef = useRef2(null);
|
|
138
130
|
const spaceReady = useRef2(new Trigger());
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
131
|
+
const [spaceId, setSpaceId] = useState2();
|
|
132
|
+
const clients = useMemo(() => {
|
|
133
|
+
const buidler = new TestBuilder2();
|
|
134
|
+
return Array.from({
|
|
135
|
+
length: numClients
|
|
136
|
+
}).map(() => {
|
|
137
|
+
return {
|
|
138
|
+
services: buidler.createLocalClientServices()
|
|
139
|
+
};
|
|
147
140
|
});
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
141
|
+
}, [
|
|
142
|
+
numClients
|
|
143
|
+
]);
|
|
144
|
+
const handleInitialized = useCallback(async (client, index) => {
|
|
145
|
+
if (index === 0) {
|
|
146
|
+
const { space } = await initializeClient(client, {
|
|
147
|
+
createIdentity,
|
|
148
|
+
createSpace,
|
|
149
|
+
onCreateSpace,
|
|
150
|
+
onCreateIdentity,
|
|
151
|
+
onInitialized
|
|
152
|
+
}, context);
|
|
153
|
+
log.info("inviting", {
|
|
154
|
+
index,
|
|
155
|
+
spaceId: space?.id
|
|
156
|
+
}, {
|
|
157
|
+
F: __dxlog_file,
|
|
158
|
+
L: 150,
|
|
159
|
+
S: void 0,
|
|
160
|
+
C: (f, a) => f(...a)
|
|
161
|
+
});
|
|
162
|
+
setSpaceId(space?.id);
|
|
163
|
+
spaceReady.current.wake(space);
|
|
164
|
+
} else {
|
|
165
|
+
await initializeClient(client, {
|
|
166
|
+
createIdentity,
|
|
167
|
+
onInitialized
|
|
168
|
+
}, context);
|
|
169
|
+
log.info("waiting", {
|
|
170
|
+
index
|
|
171
|
+
}, {
|
|
172
|
+
F: __dxlog_file,
|
|
173
|
+
L: 157,
|
|
174
|
+
S: void 0,
|
|
175
|
+
C: (f, a) => f(...a)
|
|
176
|
+
});
|
|
177
|
+
const space = await spaceReady.current.wait();
|
|
178
|
+
if (space) {
|
|
179
|
+
log.info("joining", {
|
|
180
|
+
index,
|
|
181
|
+
spaceId: space.id
|
|
161
182
|
}, {
|
|
162
183
|
F: __dxlog_file,
|
|
163
|
-
L:
|
|
184
|
+
L: 160,
|
|
164
185
|
S: void 0,
|
|
165
186
|
C: (f, a) => f(...a)
|
|
166
187
|
});
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}, context);
|
|
172
|
-
const space = await spaceReady.current.wait();
|
|
173
|
-
if (space) {
|
|
174
|
-
log.info("joining", {
|
|
175
|
-
index
|
|
176
|
-
}, {
|
|
177
|
-
F: __dxlog_file,
|
|
178
|
-
L: 154,
|
|
179
|
-
S: void 0,
|
|
180
|
-
C: (f, a) => f(...a)
|
|
181
|
-
});
|
|
182
|
-
await Promise.all(performInvitation2({
|
|
183
|
-
host: space,
|
|
184
|
-
guest: client.spaces
|
|
185
|
-
}));
|
|
186
|
-
}
|
|
188
|
+
await Promise.all(performInvitation2({
|
|
189
|
+
host: space,
|
|
190
|
+
guest: client.spaces
|
|
191
|
+
}));
|
|
187
192
|
}
|
|
188
193
|
}
|
|
189
|
-
};
|
|
190
|
-
return /* @__PURE__ */ React2.createElement(
|
|
191
|
-
|
|
192
|
-
}
|
|
194
|
+
}, []);
|
|
195
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
196
|
+
className: "absolute inset-0 grid grid-flow-col auto-cols-fr gap-4 overflow-hidden"
|
|
197
|
+
}, clients.map((client, index) => /* @__PURE__ */ React2.createElement(ClientProvider, {
|
|
193
198
|
key: index,
|
|
199
|
+
services: client.services,
|
|
200
|
+
onInitialized: (client2) => handleInitialized(client2, index),
|
|
201
|
+
...props
|
|
202
|
+
}, /* @__PURE__ */ React2.createElement(ClientStory.Provider, {
|
|
194
203
|
value: {
|
|
195
|
-
|
|
204
|
+
index,
|
|
205
|
+
spaceId
|
|
196
206
|
}
|
|
197
|
-
}, /* @__PURE__ */ React2.createElement(
|
|
198
|
-
services: builder.current.createLocalClientServices(),
|
|
199
|
-
onInitialized: (client) => handleInitialized(client, index),
|
|
200
|
-
...props
|
|
201
|
-
}, /* @__PURE__ */ React2.createElement(Story, null)))));
|
|
207
|
+
}, /* @__PURE__ */ React2.createElement(ErrorBoundary, null, /* @__PURE__ */ React2.createElement(Story, null))))));
|
|
202
208
|
};
|
|
203
209
|
};
|
|
204
210
|
var ErrorBoundary = ({ children }) => {
|
|
205
211
|
const [error, setError] = useState2();
|
|
206
|
-
|
|
212
|
+
useEffect(() => {
|
|
207
213
|
const handleError = (event) => {
|
|
208
214
|
setError(event.reason);
|
|
209
215
|
};
|
|
@@ -240,8 +246,7 @@ var ErrorFallback = ({ error }) => {
|
|
|
240
246
|
export {
|
|
241
247
|
ClientRepeater,
|
|
242
248
|
ClientStory,
|
|
243
|
-
|
|
244
|
-
useMultiClient,
|
|
249
|
+
useClientStory,
|
|
245
250
|
withClientProvider,
|
|
246
251
|
withMultiClientProvider
|
|
247
252
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/testing/index.ts", "../../../../src/testing/context.tsx", "../../../../src/testing/ClientRepeater.tsx", "../../../../src/testing/withClientProvider.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2020 DXOS.org\n//\n\nexport * from '@dxos/client/testing';\n\nexport * from './context';\nexport * from './ClientRepeater';\nexport * from './withClientProvider';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { type Space } from '@dxos/client/echo';\nimport { raise } from '@dxos/debug';\n\nexport type ClientStory = {\n space?: Space;\n};\n\n// TODO(wittjosiah): Add to multi-client as well.\nexport const ClientStory = createContext<ClientStory | undefined>(undefined);\n\nexport const useClientProvider = (): ClientStory => {\n return useContext(ClientStory) ?? raise(new Error('Missing ClientStory'));\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport React, { type FC, useEffect, useRef, useState } from 'react';\n\nimport { Client, type PublicKey } from '@dxos/client';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { type TypedObject } from '@dxos/echo/internal';\nimport { registerSignalsRuntime } from '@dxos/echo-signals/react';\nimport { faker } from '@dxos/random';\nimport { useAsyncEffect } from '@dxos/react-hooks';\n\nimport { ClientProvider } from '../client';\n\nimport { type WithClientProviderProps } from './withClientProvider';\n\nexport type ClientRepeatedComponentProps = { id: number; count: number; spaceKey?: PublicKey };\n\nexport type ClientRepeaterControlsProps = { clients: Client[] };\n\n// TODO(burdon): Reconcile with ClientProviderProps.\nexport type ClientRepeaterProps<P extends ClientRepeatedComponentProps> = {\n className?: string;\n component: FC<ClientRepeatedComponentProps>;\n controls?: FC<ClientRepeaterControlsProps>;\n count?: number;\n clients?: Client[];\n types?: TypedObject[];\n args?: Omit<P, 'id' | 'count'>;\n} & Pick<WithClientProviderProps, 'createIdentity' | 'createSpace' | 'onCreateSpace'>;\n\n/**\n * Utility component for Storybook stories which sets up clients for n peers.\n * The `Component` property is rendered n times, once for each peer.\n * @deprecated use `withClientProvider`.\n */\n// TODO(burdon): To discuss: evolve ClientRepeater with optional decorator that uses it.\n// NOTE: This is specifically not a storybook decorator because it broke stories as a decorator.\n// This seems primarily due to the fact that it required top-level await for the clients to initialize.\n// Storybook seemed to handle it alright, but Chromatic had a lot of trouble with it.\n// There was also a question of whether or not calling the story function multiple times was a good idea.\nexport const ClientRepeater = <P extends ClientRepeatedComponentProps>(props: ClientRepeaterProps<P>) => {\n const {\n component: Component,\n controls: Controls,\n count = 1,\n types,\n createIdentity,\n createSpace,\n onCreateSpace,\n } = props;\n useEffect(() => {\n registerSignalsRuntime();\n }, []);\n\n const [clients, setClients] = useState(props.clients ?? []);\n const [spaceKey, setSpaceKey] = useState<PublicKey>();\n\n const testBuilder = useRef(new TestBuilder());\n useAsyncEffect(async () => {\n const clients = [...Array(count)].map(\n (_) => new Client({ services: testBuilder.current.createLocalClientServices(), types }),\n );\n\n await Promise.all(clients.map((client) => client.initialize()));\n if (createIdentity || createSpace) {\n await Promise.all(clients.map((client) => client.halo.createIdentity()));\n }\n\n if (createSpace) {\n const client = clients[0];\n const space = await client.spaces.create({ name: faker.commerce.productName() });\n setSpaceKey(space.key);\n await onCreateSpace?.({ client, space }, {});\n await Promise.all(clients.slice(1).flatMap((client) => performInvitation({ host: space, guest: client.spaces })));\n }\n\n setClients(clients);\n }, []);\n\n if (clients.length === 0) {\n return null;\n }\n\n return (\n <>\n {Controls && <Controls clients={clients} />}\n {clients.map((client, index) => (\n <ClientProvider key={index} client={client}>\n <Component id={index} count={clients.length} spaceKey={spaceKey} {...{ ...props.args }} />\n </ClientProvider>\n ))}\n </>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Decorator, type StoryContext } from '@storybook/react';\nimport React, { type PropsWithChildren, createContext, useContext, useEffect, useRef, useState } from 'react';\nimport { type FallbackProps, ErrorBoundary as NaturalErrorBoundary } from 'react-error-boundary';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { log } from '@dxos/log';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { ClientProvider, type ClientProviderProps } from '../client';\n\nimport { ClientStory } from './context';\n\ntype InitializeProps = {\n createIdentity?: boolean;\n createSpace?: boolean;\n onInitialized?: (client: Client) => MaybePromise<void>;\n onCreateIdentity?: (props: { client: Client }, context: StoryContext | any) => MaybePromise<void>;\n // NOTE: context must be untyped until ClientRepeater is removed.\n onCreateSpace?: (props: { client: Client; space: Space }, context: StoryContext | any) => MaybePromise<void>;\n};\n\n/**\n * Initialize client, identity and first space.\n */\nconst initializeClient = async (\n client: Client,\n { createIdentity, createSpace, onCreateIdentity, onCreateSpace, onInitialized }: InitializeProps,\n context: StoryContext,\n): Promise<ClientStory> => {\n await onInitialized?.(client);\n\n if (createIdentity || createSpace) {\n if (!client.halo.identity.get()) {\n await client.halo.createIdentity();\n await client.spaces.waitUntilReady();\n await client.spaces.default.waitUntilReady();\n await onCreateIdentity?.({ client }, context);\n }\n }\n\n let space: Space | undefined;\n if (createSpace) {\n space = await client.spaces.create({ name: 'Test Space' });\n await space.waitUntilReady(); // Is this required?\n await onCreateSpace?.({ client, space }, context);\n }\n\n return { space };\n};\n\nexport type WithClientProviderProps = InitializeProps & Omit<ClientProviderProps, 'onInitialized'>;\n\n/**\n * Decorator that provides the client context.\n */\nexport const withClientProvider = ({\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n ...props\n}: WithClientProviderProps = {}): Decorator => {\n return (Story, context) => {\n const [data, setData] = useState<ClientStory>({});\n const handleInitialized = async (client: Client) => {\n const data = await initializeClient(\n client,\n {\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n },\n context,\n );\n\n setData(data);\n };\n\n return (\n <ErrorBoundary>\n <ClientProvider onInitialized={handleInitialized} {...props}>\n <ClientStory.Provider value={data}>\n <Story />\n </ClientStory.Provider>\n </ClientProvider>\n </ErrorBoundary>\n );\n };\n};\n\n// TODO(burdon): Implement context per client for context.\n// TODO(burdon): Callback once all invitations have completed.\n// TODO(burdon): Delay/jitter for creation of other clients.\nexport type WithMultiClientProviderProps = InitializeProps &\n Omit<ClientProviderProps, 'onInitialized'> & { numClients?: number };\n\nconst MultiClientContext = createContext<{ id: number }>({ id: 0 });\n\nexport const useMultiClient = () => useContext(MultiClientContext);\n\n/**\n * Decorator that creates a scaffold for multiple clients.\n * Orchestrates invitations between a randomly selected host and the remaining clients.\n */\nexport const withMultiClientProvider = ({\n numClients = 2,\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n ...props\n}: WithMultiClientProviderProps): Decorator => {\n return (Story, context) => {\n const builder = useRef(new TestBuilder());\n const hostRef = useRef<Client>(null);\n const spaceReady = useRef(new Trigger<Space | undefined>());\n\n // Handle invitations.\n // NOTE: The zeroth client isn't necessarily the first to be initialized.\n const handleInitialized = async (client: Client, index: number) => {\n log.info('initialized', { index });\n if (createSpace) {\n if (!hostRef.current) {\n hostRef.current = client;\n const { space } = await initializeClient(\n client,\n {\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n },\n context,\n );\n\n spaceReady.current.wake(space);\n log.info('inviting', { index });\n } else {\n await initializeClient(client, { createIdentity, onInitialized }, context);\n const space = await spaceReady.current.wait();\n if (space) {\n log.info('joining', { index });\n await Promise.all(performInvitation({ host: space, guest: client.spaces }));\n }\n }\n }\n };\n\n return (\n <ErrorBoundary>\n {Array.from({ length: numClients }).map((_, index) => (\n <MultiClientContext.Provider key={index} value={{ id: index }}>\n <ClientProvider\n services={builder.current.createLocalClientServices()}\n onInitialized={(client) => handleInitialized(client, index)}\n {...props}\n >\n <Story />\n </ClientProvider>\n </MultiClientContext.Provider>\n ))}\n </ErrorBoundary>\n );\n };\n};\n\nconst ErrorBoundary = ({ children }: PropsWithChildren) => {\n const [error, setError] = useState<Error>();\n useEffect(() => {\n const handleError = (event: PromiseRejectionEvent) => {\n setError(event.reason);\n };\n\n window.addEventListener('unhandledrejection', handleError);\n return () => window.removeEventListener('unhandledrejection', handleError);\n }, []);\n\n if (error) {\n return <ErrorFallback error={error} resetErrorBoundary={() => setError(undefined)} />;\n }\n\n return <NaturalErrorBoundary FallbackComponent={ErrorFallback}>{children}</NaturalErrorBoundary>;\n};\n\nconst ErrorFallback = ({ error }: FallbackProps) => {\n const { name, message, stack } =\n error instanceof Error ? error : { name: 'Error', message: String(error), stack: undefined };\n return (\n <div role='alert' className='flex flex-col p-4 gap-4 overflow-auto'>\n <h1 className='text-xl text-red-500'>{name}</h1>\n <div className='text-lg'>{message}</div>\n {stack && <pre className='whitespace-pre-wrap text-sm text-subdued'>{stack}</pre>}\n </div>\n );\n};\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["createContext", "useContext", "raise", "ClientStory", "createContext", "undefined", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2020 DXOS.org\n//\n\nexport * from '@dxos/client/testing';\n\nexport * from './context';\nexport * from './ClientRepeater';\nexport * from './withClientProvider';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { type Space, type SpaceId } from '@dxos/client/echo';\nimport { raise } from '@dxos/debug';\n\nexport type ClientStory = {\n index?: number;\n spaceId?: SpaceId;\n space?: Space;\n};\n\nexport const ClientStory = createContext<ClientStory | undefined>(undefined);\n\nexport const useClientStory = (): ClientStory => {\n return useContext(ClientStory) ?? raise(new Error('Missing ClientStory'));\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport React, { type FC, useRef, useState } from 'react';\n\nimport { Client } from '@dxos/client';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { type Type } from '@dxos/echo';\nimport { faker } from '@dxos/random';\nimport { useAsyncEffect } from '@dxos/react-hooks';\n\nimport { ClientProvider } from '../client';\nimport { type SpaceId } from '../echo';\n\nimport { type WithClientProviderProps } from './withClientProvider';\n\nexport type ClientRepeatedComponentProps = { id: number; count: number; spaceId?: SpaceId };\n\nexport type ClientRepeaterControlsProps = { clients: Client[] };\n\n// TODO(burdon): Reconcile with ClientProviderProps.\nexport type ClientRepeaterProps<P extends ClientRepeatedComponentProps> = {\n className?: string;\n component: FC<ClientRepeatedComponentProps>;\n controls?: FC<ClientRepeaterControlsProps>;\n count?: number;\n clients?: Client[];\n types?: Type.Obj.Any[];\n args?: Omit<P, 'id' | 'count'>;\n} & Pick<WithClientProviderProps, 'createIdentity' | 'createSpace' | 'onCreateSpace'>;\n\n/**\n * Utility component for Storybook stories which sets up clients for n peers.\n * The `Component` property is rendered n times, once for each peer.\n * @deprecated use `withClientProvider`.\n */\n// TODO(burdon): To discuss: evolve ClientRepeater with optional decorator that uses it.\n// NOTE: This is specifically not a storybook decorator because it broke stories as a decorator.\n// This seems primarily due to the fact that it required top-level await for the clients to initialize.\n// Storybook seemed to handle it alright, but Chromatic had a lot of trouble with it.\n// There was also a question of whether or not calling the story function multiple times was a good idea.\nexport const ClientRepeater = <P extends ClientRepeatedComponentProps>(props: ClientRepeaterProps<P>) => {\n const {\n component: Component,\n controls: Controls,\n count = 1,\n types,\n createIdentity,\n createSpace,\n onCreateSpace,\n } = props;\n\n const [clients, setClients] = useState(props.clients ?? []);\n const [spaceId, setSpaceId] = useState<SpaceId>();\n\n const testBuilder = useRef(new TestBuilder());\n useAsyncEffect(async () => {\n const clients = [...Array(count)].map(\n (_) => new Client({ services: testBuilder.current.createLocalClientServices(), types }),\n );\n\n await Promise.all(clients.map((client) => client.initialize()));\n if (createIdentity || createSpace) {\n await Promise.all(clients.map((client) => client.halo.createIdentity()));\n }\n\n if (createSpace) {\n const client = clients[0];\n const space = await client.spaces.create({ name: faker.commerce.productName() });\n setSpaceId(space.id);\n await onCreateSpace?.({ client, space }, {});\n await Promise.all(clients.slice(1).flatMap((client) => performInvitation({ host: space, guest: client.spaces })));\n }\n\n setClients(clients);\n }, []);\n\n if (clients.length === 0) {\n return null;\n }\n\n return (\n <>\n {Controls && <Controls clients={clients} />}\n {clients.map((client, index) => (\n <ClientProvider key={index} client={client}>\n <Component id={index} count={clients.length} spaceId={spaceId} {...{ ...props.args }} />\n </ClientProvider>\n ))}\n </>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Decorator, type StoryContext } from '@storybook/react';\nimport React, { type PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { type FallbackProps, ErrorBoundary as NaturalErrorBoundary } from 'react-error-boundary';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { type Space, type SpaceId } from '@dxos/client/echo';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { log } from '@dxos/log';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { ClientProvider, type ClientProviderProps } from '../client';\n\nimport { ClientStory } from './context';\n\ntype InitializeProps = {\n createIdentity?: boolean;\n createSpace?: boolean;\n onInitialized?: (client: Client) => MaybePromise<void>;\n onCreateIdentity?: (props: { client: Client }, context: StoryContext | any) => MaybePromise<void>;\n // NOTE: context must be untyped until ClientRepeater is removed.\n onCreateSpace?: (props: { client: Client; space: Space }, context: StoryContext | any) => MaybePromise<void>;\n};\n\n/**\n * Initialize client, identity and first space.\n */\nconst initializeClient = async (\n client: Client,\n { createIdentity, createSpace, onCreateIdentity, onCreateSpace, onInitialized }: InitializeProps,\n context: StoryContext,\n): Promise<ClientStory> => {\n await onInitialized?.(client);\n\n if (createIdentity || createSpace) {\n if (!client.halo.identity.get()) {\n await client.halo.createIdentity();\n await client.spaces.waitUntilReady();\n await client.spaces.default.waitUntilReady();\n await onCreateIdentity?.({ client }, context);\n }\n }\n\n let space: Space | undefined;\n if (createSpace) {\n space = await client.spaces.create({ name: 'Test Space' });\n await space.waitUntilReady(); // Is this required?\n await onCreateSpace?.({ client, space }, context);\n }\n\n return { space, spaceId: space?.id };\n};\n\nexport type WithClientProviderProps = InitializeProps & Omit<ClientProviderProps, 'onInitialized'>;\n\n/**\n * Decorator that provides the client context.\n */\nexport const withClientProvider = ({\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n ...props\n}: WithClientProviderProps = {}): Decorator => {\n return (Story, context) => {\n const [data, setData] = useState<ClientStory>({});\n const handleInitialized = async (client: Client) => {\n const data = await initializeClient(\n client,\n {\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n },\n context,\n );\n\n setData(data);\n };\n\n return (\n <ErrorBoundary>\n <ClientProvider onInitialized={handleInitialized} {...props}>\n <ClientStory.Provider value={data}>\n <Story />\n </ClientStory.Provider>\n </ClientProvider>\n </ErrorBoundary>\n );\n };\n};\n\n// TODO(burdon): Implement context per client for context.\n// TODO(burdon): Callback once all invitations have completed.\n// TODO(burdon): Delay/jitter for creation of other clients.\nexport type WithMultiClientProviderProps = InitializeProps &\n Omit<ClientProviderProps, 'onInitialized'> & { numClients?: number };\n\n/**\n * Decorator that creates a scaffold for multiple clients.\n * Orchestrates invitations between a randomly selected host and the remaining clients.\n */\nexport const withMultiClientProvider = ({\n numClients = 2,\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n ...props\n}: WithMultiClientProviderProps): Decorator => {\n return (Story, context) => {\n const spaceReady = useRef(new Trigger<Space | undefined>());\n const [spaceId, setSpaceId] = useState<SpaceId>();\n\n const clients = useMemo(() => {\n const buidler = new TestBuilder();\n return Array.from({ length: numClients }).map(() => {\n return {\n services: buidler.createLocalClientServices(),\n };\n });\n }, [numClients]);\n\n // Handle invitations.\n // NOTE: The zeroth client isn't necessarily the first to be initialized.\n const handleInitialized = useCallback(async (client: Client, index: number) => {\n if (index === 0) {\n // Initialize host.\n const { space } = await initializeClient(\n client,\n {\n createIdentity,\n createSpace,\n onCreateSpace,\n onCreateIdentity,\n onInitialized,\n },\n context,\n );\n\n log.info('inviting', { index, spaceId: space?.id });\n setSpaceId(space?.id);\n spaceReady.current.wake(space);\n } else {\n // Initialize guest.\n await initializeClient(client, { createIdentity, onInitialized }, context);\n\n log.info('waiting', { index });\n const space = await spaceReady.current.wait();\n if (space) {\n log.info('joining', { index, spaceId: space.id });\n await Promise.all(\n performInvitation({\n host: space,\n guest: client.spaces,\n }),\n );\n }\n }\n }, []);\n\n return (\n <div className='absolute inset-0 grid grid-flow-col auto-cols-fr gap-4 overflow-hidden'>\n {clients.map((client, index) => (\n <ClientProvider\n key={index}\n services={client.services}\n onInitialized={(client) => handleInitialized(client, index)}\n {...props}\n >\n <ClientStory.Provider value={{ index, spaceId }}>\n <ErrorBoundary>\n <Story />\n </ErrorBoundary>\n </ClientStory.Provider>\n </ClientProvider>\n ))}\n </div>\n );\n };\n};\n\nconst ErrorBoundary = ({ children }: PropsWithChildren) => {\n const [error, setError] = useState<Error>();\n useEffect(() => {\n const handleError = (event: PromiseRejectionEvent) => {\n setError(event.reason);\n };\n\n window.addEventListener('unhandledrejection', handleError);\n return () => window.removeEventListener('unhandledrejection', handleError);\n }, []);\n\n if (error) {\n return <ErrorFallback error={error} resetErrorBoundary={() => setError(undefined)} />;\n }\n\n return <NaturalErrorBoundary FallbackComponent={ErrorFallback}>{children}</NaturalErrorBoundary>;\n};\n\nconst ErrorFallback = ({ error }: FallbackProps) => {\n const { name, message, stack } =\n error instanceof Error ? error : { name: 'Error', message: String(error), stack: undefined };\n\n return (\n <div role='alert' className='flex flex-col p-4 gap-4 overflow-auto'>\n <h1 className='text-xl text-red-500'>{name}</h1>\n <div className='text-lg'>{message}</div>\n {stack && <pre className='whitespace-pre-wrap text-sm text-subdued'>{stack}</pre>}\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["createContext", "useContext", "raise", "ClientStory", "createContext", "undefined", "useClientStory", "useContext", "raise", "Error", "React", "useRef", "useState", "Client", "TestBuilder", "performInvitation", "faker", "useAsyncEffect", "ClientRepeater", "props", "component", "Component", "controls", "Controls", "count", "types", "createIdentity", "createSpace", "onCreateSpace", "clients", "setClients", "useState", "spaceId", "setSpaceId", "testBuilder", "useRef", "TestBuilder", "useAsyncEffect", "Array", "map", "_", "Client", "services", "current", "createLocalClientServices", "Promise", "all", "client", "initialize", "halo", "space", "spaces", "create", "name", "faker", "commerce", "productName", "id", "slice", "flatMap", "performInvitation", "host", "guest", "length", "index", "ClientProvider", "key", "args", "React", "useCallback", "useEffect", "useMemo", "useRef", "useState", "ErrorBoundary", "NaturalErrorBoundary", "Trigger", "TestBuilder", "performInvitation", "log", "initializeClient", "client", "createIdentity", "createSpace", "onCreateIdentity", "onCreateSpace", "onInitialized", "context", "halo", "identity", "get", "spaces", "waitUntilReady", "default", "space", "create", "name", "spaceId", "id", "withClientProvider", "props", "Story", "data", "setData", "useState", "handleInitialized", "React", "ErrorBoundary", "ClientProvider", "ClientStory", "Provider", "value", "withMultiClientProvider", "numClients", "spaceReady", "useRef", "Trigger", "setSpaceId", "clients", "useMemo", "buidler", "TestBuilder", "Array", "from", "length", "map", "services", "createLocalClientServices", "useCallback", "index", "log", "info", "current", "wake", "wait", "Promise", "all", "performInvitation", "host", "guest", "div", "className", "key", "children", "error", "setError", "useEffect", "handleError", "event", "reason", "window", "addEventListener", "removeEventListener", "ErrorFallback", "resetErrorBoundary", "undefined", "NaturalErrorBoundary", "FallbackComponent", "message", "stack", "Error", "String", "role", "h1", "pre"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/client/context.ts
|
|
4
|
+
import { createContext } from "react";
|
|
5
|
+
var ClientContext = createContext(void 0);
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
ClientContext
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=chunk-373DPHEQ.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/client/context.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2020 DXOS.org\n//\n\nimport { type Context, createContext } from 'react';\n\nimport { type Client, type SystemStatus } from '@dxos/client';\n\nexport type ClientContextProps = {\n client: Client;\n status?: SystemStatus | null;\n};\n\n/**\n * @internal Use ClientProvider to create or initialize the Client.\n */\nexport const ClientContext: Context<ClientContextProps | undefined> = createContext<ClientContextProps | undefined>(\n undefined,\n);\n"],
|
|
5
|
+
"mappings": ";;;AAIA,SAAuBA,qBAAqB;AAYrC,IAAMC,gBAAyDC,cACpEC,MAAAA;",
|
|
6
|
+
"names": ["createContext", "ClientContext", "createContext", "undefined"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ClientContext
|
|
4
|
+
} from "./chunk-373DPHEQ.mjs";
|
|
5
|
+
|
|
6
|
+
// src/client/useClient.ts
|
|
7
|
+
import { useContext } from "react";
|
|
8
|
+
import { raise } from "@dxos/debug";
|
|
9
|
+
var useClient = () => {
|
|
10
|
+
const { client } = useContext(ClientContext) ?? raise(new Error("Missing ClientContext."));
|
|
11
|
+
return client;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
useClient
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=chunk-NETTSER2.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/client/useClient.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { ClientContext } from '../client/context';\n\n/**\n * Hook returning instance of DXOS client.\n * Requires ClientContext to be set via ClientProvider.\n */\nexport const useClient = () => {\n const { client } = useContext(ClientContext) ?? raise(new Error('Missing ClientContext.'));\n return client;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;AAIA,SAASA,kBAAkB;AAE3B,SAASC,aAAa;AAQf,IAAMC,YAAY,MAAA;AACvB,QAAM,EAAEC,OAAM,IAAKC,WAAWC,aAAAA,KAAkBC,MAAM,IAAIC,MAAM,wBAAA,CAAA;AAChE,SAAOJ;AACT;",
|
|
6
|
+
"names": ["useContext", "raise", "useClient", "client", "useContext", "ClientContext", "raise", "Error"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ClientContext
|
|
4
|
+
} from "./chunk-373DPHEQ.mjs";
|
|
5
|
+
|
|
6
|
+
// src/client/ClientProvider.tsx
|
|
7
|
+
import React, { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
|
8
|
+
import { Client, SystemStatus } from "@dxos/client";
|
|
9
|
+
import { log } from "@dxos/log";
|
|
10
|
+
import { useAsyncEffect, useControlledState } from "@dxos/react-hooks";
|
|
11
|
+
import { getAsyncProviderValue } from "@dxos/util";
|
|
12
|
+
|
|
13
|
+
// src/banner.ts
|
|
14
|
+
var BANNER = (client) => {
|
|
15
|
+
const commitHash = client.config.get("runtime.app.build.commitHash");
|
|
16
|
+
const hash = commitHash ? ` App Commit ${commitHash}
|
|
17
|
+
` : "";
|
|
18
|
+
return `
|
|
19
|
+
_/\\/\\/\\/\\/\\____/\\/\\____/\\/\\____/\\/\\/\\/\\______/\\/\\/\\/\\/\\_
|
|
20
|
+
_/\\/\\____/\\/\\____/\\/\\/\\/\\____/\\/\\____/\\/\\__/\\/\\_________
|
|
21
|
+
_/\\/\\____/\\/\\______/\\/\\______/\\/\\____/\\/\\____/\\/\\/\\/\\___
|
|
22
|
+
_/\\/\\____/\\/\\____/\\/\\/\\/\\____/\\/\\____/\\/\\__________/\\/\\_
|
|
23
|
+
_/\\/\\/\\/\\/\\____/\\/\\____/\\/\\____/\\/\\/\\/\\____/\\/\\/\\/\\/\\___
|
|
24
|
+
|
|
25
|
+
DXOS Client ${client.version}
|
|
26
|
+
${hash}`;
|
|
27
|
+
};
|
|
28
|
+
var bannerPrinted = false;
|
|
29
|
+
var printBanner = (client) => {
|
|
30
|
+
if (bannerPrinted || window.location.hostname === "localhost") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
bannerPrinted = true;
|
|
34
|
+
console.log(`%c${BANNER(client)}`, "font-family: monospace;");
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/client/ClientProvider.tsx
|
|
38
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/react-client/src/client/ClientProvider.tsx";
|
|
39
|
+
var ClientProvider = /* @__PURE__ */ forwardRef(({ children, config: configProp, client: clientProp, services: servicesProp, status: statusProp, fallback: Fallback = () => null, noBanner, onInitialized, ...options }, forwardedRef) => {
|
|
40
|
+
const [error, setError] = useState();
|
|
41
|
+
if (error) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
const [client, setClient] = useState(clientProp instanceof Client ? clientProp : void 0);
|
|
45
|
+
useImperativeHandle(forwardedRef, () => client, [
|
|
46
|
+
client
|
|
47
|
+
]);
|
|
48
|
+
const [status, setStatus] = useControlledState(statusProp);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (!client) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const subscription = client.status.subscribe((status2) => setStatus(status2));
|
|
54
|
+
return () => subscription.unsubscribe();
|
|
55
|
+
}, [
|
|
56
|
+
client
|
|
57
|
+
]);
|
|
58
|
+
useAsyncEffect(async () => {
|
|
59
|
+
let disposed = false;
|
|
60
|
+
const initialize = async (client3) => {
|
|
61
|
+
if (!client3.initialized) {
|
|
62
|
+
await client3.initialize().catch((err) => {
|
|
63
|
+
if (!disposed) {
|
|
64
|
+
setError(err);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
log("client ready", void 0, {
|
|
68
|
+
F: __dxlog_file,
|
|
69
|
+
L: 124,
|
|
70
|
+
S: void 0,
|
|
71
|
+
C: (f, a) => f(...a)
|
|
72
|
+
});
|
|
73
|
+
await onInitialized?.(client3);
|
|
74
|
+
log("initialization complete", void 0, {
|
|
75
|
+
F: __dxlog_file,
|
|
76
|
+
L: 126,
|
|
77
|
+
S: void 0,
|
|
78
|
+
C: (f, a) => f(...a)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
setClient(client3);
|
|
82
|
+
if (!noBanner) {
|
|
83
|
+
printBanner(client3);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
let client2;
|
|
87
|
+
try {
|
|
88
|
+
if (clientProp) {
|
|
89
|
+
client2 = await getAsyncProviderValue(clientProp);
|
|
90
|
+
await initialize(client2);
|
|
91
|
+
} else {
|
|
92
|
+
const config = await getAsyncProviderValue(configProp);
|
|
93
|
+
log("resolved config", {
|
|
94
|
+
config
|
|
95
|
+
}, {
|
|
96
|
+
F: __dxlog_file,
|
|
97
|
+
L: 144,
|
|
98
|
+
S: void 0,
|
|
99
|
+
C: (f, a) => f(...a)
|
|
100
|
+
});
|
|
101
|
+
const services = await getAsyncProviderValue(servicesProp, config);
|
|
102
|
+
log("created services", {
|
|
103
|
+
services
|
|
104
|
+
}, {
|
|
105
|
+
F: __dxlog_file,
|
|
106
|
+
L: 146,
|
|
107
|
+
S: void 0,
|
|
108
|
+
C: (f, a) => f(...a)
|
|
109
|
+
});
|
|
110
|
+
client2 = new Client({
|
|
111
|
+
config,
|
|
112
|
+
services,
|
|
113
|
+
...options
|
|
114
|
+
});
|
|
115
|
+
log("created client", void 0, {
|
|
116
|
+
F: __dxlog_file,
|
|
117
|
+
L: 148,
|
|
118
|
+
S: void 0,
|
|
119
|
+
C: (f, a) => f(...a)
|
|
120
|
+
});
|
|
121
|
+
await initialize(client2);
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (!disposed) {
|
|
125
|
+
log.catch(err, void 0, {
|
|
126
|
+
F: __dxlog_file,
|
|
127
|
+
L: 153,
|
|
128
|
+
S: void 0,
|
|
129
|
+
C: (f, a) => f(...a)
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return () => {
|
|
134
|
+
log("clean up", void 0, {
|
|
135
|
+
F: __dxlog_file,
|
|
136
|
+
L: 158,
|
|
137
|
+
S: void 0,
|
|
138
|
+
C: (f, a) => f(...a)
|
|
139
|
+
});
|
|
140
|
+
disposed = true;
|
|
141
|
+
if (!clientProp) {
|
|
142
|
+
void client2?.destroy().then(() => {
|
|
143
|
+
log("destroyed", void 0, {
|
|
144
|
+
F: __dxlog_file,
|
|
145
|
+
L: 165,
|
|
146
|
+
S: void 0,
|
|
147
|
+
C: (f, a) => f(...a)
|
|
148
|
+
});
|
|
149
|
+
}).catch((err) => log.catch(err, void 0, {
|
|
150
|
+
F: __dxlog_file,
|
|
151
|
+
L: 167,
|
|
152
|
+
S: void 0,
|
|
153
|
+
C: (f, a) => f(...a)
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}, [
|
|
158
|
+
configProp,
|
|
159
|
+
clientProp,
|
|
160
|
+
servicesProp,
|
|
161
|
+
noBanner
|
|
162
|
+
]);
|
|
163
|
+
if (!client?.initialized || status !== SystemStatus.ACTIVE) {
|
|
164
|
+
return /* @__PURE__ */ React.createElement(Fallback, {
|
|
165
|
+
client,
|
|
166
|
+
status
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return /* @__PURE__ */ React.createElement(ClientContext.Provider, {
|
|
170
|
+
value: {
|
|
171
|
+
client,
|
|
172
|
+
status
|
|
173
|
+
}
|
|
174
|
+
}, children);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
ClientProvider
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=chunk-T3QTQHBD.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/client/ClientProvider.tsx", "../../../src/banner.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2020 DXOS.org\n//\n\nimport React, {\n type FunctionComponent,\n type PropsWithChildren,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react';\n\nimport { Client, type ClientOptions, type ClientServicesProvider, SystemStatus } from '@dxos/client';\nimport { type Config } from '@dxos/config';\nimport { log } from '@dxos/log';\nimport { useAsyncEffect, useControlledState } from '@dxos/react-hooks';\nimport { type MaybePromise, type Provider, getAsyncProviderValue } from '@dxos/util';\n\nimport { printBanner } from '../banner';\n\nimport { ClientContext, type ClientContextProps } from './context';\n\n/**\n * Properties for the ClientProvider.\n */\nexport type ClientProviderProps = Omit<ClientOptions, 'config' | 'services'> &\n Pick<ClientContextProps, 'status'> &\n PropsWithChildren<{\n /**\n * Client object or async provider to enable to caller to do custom initialization.\n *\n * NOTE: For advanced use cases only.\n */\n client?: Client | Provider<Promise<Client>>;\n\n /**\n * Config object or async provider.\n *\n * NOTE: If a `client` is provided then `config` is ignored.\n */\n // TODO(burdon): Reconcile with ClientOptions.\n config?: Config | Provider<Promise<Config>>;\n\n /**\n * Callback to enable the caller to create a custom ClientServicesProvider.\n *\n * NOTE: If a `client` is provided then `services` is ignored.\n */\n // TODO(burdon): Reconcile with ClientOptions.\n services?: ClientServicesProvider | ((config?: Config) => MaybePromise<ClientServicesProvider>);\n\n /**\n * ReactNode to display until the client is available.\n */\n fallback?: FunctionComponent<Partial<ClientContextProps>>;\n\n /**\n * Skip the DXOS banner.\n */\n noBanner?: boolean;\n\n /**\n * Post initialization hook to enable to caller to do custom initialization.\n */\n onInitialized?: (client: Client) => MaybePromise<void>;\n }>;\n\n/**\n * Root component that provides the DXOS client instance to child components.\n * To be used with the `useClient` hook.\n */\nexport const ClientProvider = forwardRef<Client | undefined, ClientProviderProps>(\n (\n {\n children,\n config: configProp,\n client: clientProp,\n services: servicesProp,\n status: statusProp,\n fallback: Fallback = () => null,\n noBanner,\n onInitialized,\n ...options\n },\n forwardedRef,\n ) => {\n // The client is initialized asynchronously.\n // If an error occurs during initialization, it is caught and the state is set.\n // This allows the error to be thrown in the render method.\n // The assumption is that a client initialization error is fatal to the app.\n // This error will be caught by the nearest error boundary.\n const [error, setError] = useState();\n if (error) {\n throw error;\n }\n\n const [client, setClient] = useState(clientProp instanceof Client ? clientProp : undefined);\n\n // Provide external access.\n useImperativeHandle(forwardedRef, () => client, [client]);\n\n // Client status subscription.\n const [status, setStatus] = useControlledState(statusProp);\n useEffect(() => {\n if (!client) {\n return;\n }\n\n const subscription = client.status.subscribe((status) => setStatus(status));\n return () => subscription.unsubscribe();\n }, [client]);\n\n // Create and/or initialize client.\n useAsyncEffect(async () => {\n let disposed = false;\n const initialize = async (client: Client) => {\n if (!client.initialized) {\n await client.initialize().catch((err) => {\n if (!disposed) {\n setError(err);\n }\n });\n log('client ready');\n await onInitialized?.(client);\n log('initialization complete');\n }\n\n setClient(client);\n if (!noBanner) {\n printBanner(client);\n }\n };\n\n let client: Client;\n try {\n if (clientProp) {\n // Asynchronously request client.\n client = await getAsyncProviderValue(clientProp);\n await initialize(client);\n } else {\n // Asynchronously construct client (config may be undefined).\n const config = await getAsyncProviderValue(configProp);\n log('resolved config', { config });\n const services = await getAsyncProviderValue(servicesProp, config);\n log('created services', { services });\n client = new Client({ config, services, ...options });\n log('created client');\n await initialize(client);\n }\n } catch (err) {\n if (!disposed) {\n log.catch(err);\n }\n }\n\n return () => {\n log('clean up');\n disposed = true;\n // Only destroy if the client is not provided by the parent.\n if (!clientProp) {\n void client\n ?.destroy()\n .then(() => {\n log('destroyed');\n })\n .catch((err) => log.catch(err));\n }\n };\n }, [configProp, clientProp, servicesProp, noBanner]);\n\n if (!client?.initialized || status !== SystemStatus.ACTIVE) {\n return <Fallback client={client} status={status} />;\n }\n\n return <ClientContext.Provider value={{ client, status }}>{children}</ClientContext.Provider>;\n },\n);\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Client } from '@dxos/client';\n\n// http://patorjk.com/software/taag/#p=testall&f=Patorjk-HeX&t=DXOS\nconst BANNER = (client: Client) => {\n const commitHash = client.config.get('runtime.app.build.commitHash');\n const hash = commitHash ? ` App Commit ${commitHash} \\n` : '';\n\n return (\n '\\n' +\n '_/\\\\/\\\\/\\\\/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\______/\\\\/\\\\/\\\\/\\\\/\\\\_\\n' +\n '_/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\__/\\\\/\\\\_________\\n' +\n '_/\\\\/\\\\____/\\\\/\\\\______/\\\\/\\\\______/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\___\\n' +\n '_/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\__________/\\\\/\\\\_\\n' +\n '_/\\\\/\\\\/\\\\/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\____/\\\\/\\\\/\\\\/\\\\/\\\\___\\n' +\n `\\n DXOS Client ${client.version} \\n${hash}`\n );\n};\n\nlet bannerPrinted = false;\n\nexport const printBanner = (client: Client) => {\n if (bannerPrinted || window.location.hostname === 'localhost') {\n return;\n }\n\n bannerPrinted = true;\n // eslint-disable-next-line no-console\n console.log(`%c${BANNER(client)}`, 'font-family: monospace;');\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "forwardRef", "useEffect", "useImperativeHandle", "useState", "Client", "SystemStatus", "log", "useAsyncEffect", "useControlledState", "getAsyncProviderValue", "BANNER", "client", "commitHash", "config", "get", "hash", "version", "bannerPrinted", "printBanner", "window", "location", "hostname", "console", "log", "ClientProvider", "forwardRef", "children", "config", "configProp", "client", "clientProp", "services", "servicesProp", "status", "statusProp", "fallback", "Fallback", "noBanner", "onInitialized", "options", "forwardedRef", "error", "setError", "useState", "setClient", "Client", "undefined", "useImperativeHandle", "setStatus", "useControlledState", "useEffect", "subscription", "subscribe", "unsubscribe", "useAsyncEffect", "disposed", "initialize", "initialized", "catch", "err", "log", "printBanner", "getAsyncProviderValue", "destroy", "then", "SystemStatus", "ACTIVE", "ClientContext", "Provider", "value"]
|
|
7
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
useClient
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-NETTSER2.mjs";
|
|
5
|
+
import "../chunk-373DPHEQ.mjs";
|
|
5
6
|
|
|
6
7
|
// src/devtools/index.ts
|
|
7
8
|
export * from "@dxos/client/devtools";
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/devtools/index.ts", "../../../../src/devtools/useDevtools.ts", "../../../../src/devtools/useStream.ts"],
|
|
4
4
|
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport * from '@dxos/client/devtools';\n\nexport * from './useDevtools';\nexport * from './useStream';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type DevtoolsHost } from '@dxos/client/devtools';\nimport { raise } from '@dxos/debug';\n\nimport { useClient } from '../client';\n\nexport const useDevtools = (): DevtoolsHost => {\n const client = useClient();\n return client.services.services.DevtoolsHost ?? raise(new Error('DevtoolsHost not available.'));\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type DependencyList, useEffect, useState } from 'react';\n\nimport { type Stream } from '@dxos/codec-protobuf/stream';\nimport { log } from '@dxos/log';\n\n/**\n * Subscribe to service API streams.\n */\nexport const useStream = <T>(streamFactory: () => Stream<T>, defaultValue: T, deps: DependencyList = []): T => {\n const [value, setValue] = useState<T | undefined>(defaultValue);\n useEffect(() => {\n const stream = streamFactory();\n stream.subscribe(\n (response: T) => setValue(response),\n (err) => {\n if (err) {\n log.catch(err);\n }\n },\n );\n\n return () => {\n void stream.close();\n };\n }, deps);\n\n return value ?? defaultValue;\n};\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;AAIA,cAAc;;;ACCd,SAASA,aAAa;AAIf,IAAMC,cAAc,MAAA;AACzB,QAAMC,SAASC,UAAAA;AACf,SAAOD,OAAOE,SAASA,SAASC,gBAAgBC,MAAM,IAAIC,MAAM,6BAAA,CAAA;AAClE;;;ACRA,SAA8BC,WAAWC,gBAAgB;AAGzD,SAASC,WAAW;;AAKb,IAAMC,YAAY,CAAIC,eAAgCC,cAAiBC,OAAuB,CAAA,MAAE;AACrG,QAAM,CAACC,OAAOC,QAAAA,IAAYP,SAAwBI,YAAAA;AAClDL,YAAU,MAAA;AACR,UAAMS,SAASL,cAAAA;AACfK,WAAOC,UACL,CAACC,aAAgBH,SAASG,QAAAA,GAC1B,CAACC,QAAAA;AACC,UAAIA,KAAK;AACPV,YAAIW,MAAMD,KAAAA,QAAAA;;;;;;MACZ;IACF,CAAA;AAGF,WAAO,MAAA;AACL,WAAKH,OAAOK,MAAK;IACnB;EACF,GAAGR,IAAAA;AAEH,SAAOC,SAASF;AAClB;",
|
|
6
6
|
"names": ["raise", "useDevtools", "client", "useClient", "services", "DevtoolsHost", "raise", "Error", "useEffect", "useState", "log", "useStream", "streamFactory", "defaultValue", "deps", "value", "setValue", "stream", "subscribe", "response", "err", "catch", "close"]
|
|
7
7
|
}
|