@dxos/react-client 0.7.4 → 0.7.5-labs.5f04cf6
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/dist/lib/browser/{chunk-U4MCIYKN.mjs → chunk-Z6OJATVN.mjs} +58 -41
- package/dist/lib/browser/chunk-Z6OJATVN.mjs.map +7 -0
- package/dist/lib/browser/devtools/index.mjs +1 -1
- package/dist/lib/browser/devtools/index.mjs.map +1 -1
- package/dist/lib/browser/echo/index.mjs +1 -1
- package/dist/lib/browser/halo/index.mjs +1 -1
- package/dist/lib/browser/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 +32 -33
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node/{chunk-UJLDNXPC.cjs → chunk-DITMVTAF.cjs} +61 -44
- package/dist/lib/node/chunk-DITMVTAF.cjs.map +7 -0
- package/dist/lib/node/devtools/index.cjs +2 -2
- package/dist/lib/node/devtools/index.cjs.map +1 -1
- package/dist/lib/node/echo/index.cjs +3 -3
- package/dist/lib/node/halo/index.cjs +5 -5
- package/dist/lib/node/index.cjs +12 -12
- package/dist/lib/node/mesh/index.cjs +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +61 -63
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/lib/node-esm/{chunk-4J4SI7XJ.mjs → chunk-6QHTUQ4Z.mjs} +58 -41
- package/dist/lib/node-esm/chunk-6QHTUQ4Z.mjs.map +7 -0
- package/dist/lib/node-esm/devtools/index.mjs +1 -1
- package/dist/lib/node-esm/devtools/index.mjs.map +1 -1
- package/dist/lib/node-esm/echo/index.mjs +1 -1
- package/dist/lib/node-esm/halo/index.mjs +1 -1
- package/dist/lib/node-esm/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 +32 -33
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/client/ClientProvider.d.ts.map +1 -1
- package/dist/types/src/devtools/useStream.d.ts +1 -1
- package/dist/types/src/devtools/useStream.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/context.d.ts +7 -0
- package/dist/types/src/testing/context.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/withClientProvider.d.ts +4 -8
- package/dist/types/src/testing/withClientProvider.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +23 -23
- package/src/client/ClientProvider.tsx +26 -14
- package/src/devtools/useStream.ts +1 -1
- package/src/testing/ClientRepeater.tsx +3 -3
- package/src/testing/context.tsx +19 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/withClientProvider.tsx +37 -39
- package/tsconfig.json +61 -2
- package/dist/lib/browser/chunk-U4MCIYKN.mjs.map +0 -7
- package/dist/lib/node/chunk-UJLDNXPC.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-4J4SI7XJ.mjs.map +0 -7
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
ClientProvider
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-6QHTUQ4Z.mjs";
|
|
5
5
|
|
|
6
6
|
// packages/sdk/react-client/src/testing/index.ts
|
|
7
7
|
export * from "@dxos/client/testing";
|
|
8
8
|
|
|
9
|
+
// packages/sdk/react-client/src/testing/context.tsx
|
|
10
|
+
import { createContext, useContext } from "react";
|
|
11
|
+
import { raise } from "@dxos/debug";
|
|
12
|
+
var ClientStory = /* @__PURE__ */ createContext(void 0);
|
|
13
|
+
var useClientProvider = () => {
|
|
14
|
+
return useContext(ClientStory) ?? raise(new Error("Missing ClientStory"));
|
|
15
|
+
};
|
|
16
|
+
|
|
9
17
|
// packages/sdk/react-client/src/testing/ClientRepeater.tsx
|
|
10
18
|
import React, { useState, useEffect, useRef } from "react";
|
|
11
19
|
import { Client } from "@dxos/client";
|
|
@@ -41,7 +49,7 @@ var ClientRepeater = (props) => {
|
|
|
41
49
|
await onSpaceCreated?.({
|
|
42
50
|
client,
|
|
43
51
|
space
|
|
44
|
-
});
|
|
52
|
+
}, {});
|
|
45
53
|
await Promise.all(clients2.slice(1).flatMap((client2) => performInvitation({
|
|
46
54
|
host: space,
|
|
47
55
|
guest: client2.spaces
|
|
@@ -68,73 +76,63 @@ var ClientRepeater = (props) => {
|
|
|
68
76
|
};
|
|
69
77
|
|
|
70
78
|
// packages/sdk/react-client/src/testing/withClientProvider.tsx
|
|
71
|
-
import React2, { createContext, useContext, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
79
|
+
import React2, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
72
80
|
import { ErrorBoundary as NativeErrorBoundary } from "react-error-boundary";
|
|
73
81
|
import { Trigger } from "@dxos/async";
|
|
74
82
|
import { performInvitation as performInvitation2, TestBuilder as TestBuilder2 } from "@dxos/client/testing";
|
|
75
|
-
import { raise } from "@dxos/debug";
|
|
76
83
|
import { log } from "@dxos/log";
|
|
77
84
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/react-client/src/testing/withClientProvider.tsx";
|
|
78
|
-
var initializeClient = async (client, { createIdentity, createSpace, onSpaceCreated, onIdentityCreated, onInitialized }) => {
|
|
79
|
-
|
|
80
|
-
let identityData = {};
|
|
85
|
+
var initializeClient = async (client, { createIdentity, createSpace, onSpaceCreated, onIdentityCreated, onInitialized }, context) => {
|
|
86
|
+
await onInitialized?.(client);
|
|
81
87
|
if (createIdentity || createSpace) {
|
|
82
88
|
if (!client.halo.identity.get()) {
|
|
83
89
|
await client.halo.createIdentity();
|
|
84
|
-
|
|
90
|
+
await onIdentityCreated?.({
|
|
85
91
|
client
|
|
86
92
|
});
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
let space;
|
|
90
|
-
let spaceData = {};
|
|
91
96
|
if (createSpace) {
|
|
92
97
|
space = await client.spaces.create({
|
|
93
98
|
name: "Test Space"
|
|
94
99
|
});
|
|
95
|
-
|
|
100
|
+
await onSpaceCreated?.({
|
|
96
101
|
client,
|
|
97
102
|
space
|
|
98
|
-
});
|
|
103
|
+
}, context);
|
|
99
104
|
}
|
|
100
105
|
return {
|
|
101
|
-
space
|
|
102
|
-
...clientData,
|
|
103
|
-
...identityData,
|
|
104
|
-
...spaceData
|
|
106
|
+
space
|
|
105
107
|
};
|
|
106
108
|
};
|
|
107
|
-
var StoryClientContext = /* @__PURE__ */ createContext(void 0);
|
|
108
|
-
var useStoryClientData = () => {
|
|
109
|
-
const data = useContext(StoryClientContext) ?? raise(new Error("Missing withClientProvider decorator."));
|
|
110
|
-
return data;
|
|
111
|
-
};
|
|
112
109
|
var withClientProvider = ({ createIdentity, createSpace, onSpaceCreated, onIdentityCreated, onInitialized, ...props } = {}) => {
|
|
113
|
-
return (Story) => {
|
|
110
|
+
return (Story, context) => {
|
|
114
111
|
const [data, setData] = useState2({});
|
|
115
112
|
const handleInitialized = async (client) => {
|
|
116
|
-
|
|
113
|
+
const data2 = await initializeClient(client, {
|
|
117
114
|
createIdentity,
|
|
118
115
|
createSpace,
|
|
119
116
|
onSpaceCreated,
|
|
120
117
|
onIdentityCreated,
|
|
121
118
|
onInitialized
|
|
122
|
-
})
|
|
119
|
+
}, context);
|
|
120
|
+
setData(data2);
|
|
123
121
|
};
|
|
124
122
|
return /* @__PURE__ */ React2.createElement(ErrorBoundary, null, /* @__PURE__ */ React2.createElement(ClientProvider, {
|
|
125
123
|
onInitialized: handleInitialized,
|
|
126
124
|
...props
|
|
127
|
-
}, /* @__PURE__ */ React2.createElement(
|
|
125
|
+
}, /* @__PURE__ */ React2.createElement(ClientStory.Provider, {
|
|
128
126
|
value: data
|
|
129
127
|
}, /* @__PURE__ */ React2.createElement(Story, null))));
|
|
130
128
|
};
|
|
131
129
|
};
|
|
132
|
-
var MultiClientContext = /* @__PURE__ */
|
|
130
|
+
var MultiClientContext = /* @__PURE__ */ createContext2({
|
|
133
131
|
id: 0
|
|
134
132
|
});
|
|
135
|
-
var useMultiClient = () =>
|
|
133
|
+
var useMultiClient = () => useContext2(MultiClientContext);
|
|
136
134
|
var withMultiClientProvider = ({ numClients = 2, createIdentity, createSpace, onSpaceCreated, onIdentityCreated, onInitialized, ...props }) => {
|
|
137
|
-
return (Story) => {
|
|
135
|
+
return (Story, context) => {
|
|
138
136
|
const builder = useRef2(new TestBuilder2());
|
|
139
137
|
const hostRef = useRef2();
|
|
140
138
|
const spaceReady = useRef2(new Trigger());
|
|
@@ -143,7 +141,7 @@ var withMultiClientProvider = ({ numClients = 2, createIdentity, createSpace, on
|
|
|
143
141
|
index
|
|
144
142
|
}, {
|
|
145
143
|
F: __dxlog_file,
|
|
146
|
-
L:
|
|
144
|
+
L: 129,
|
|
147
145
|
S: void 0,
|
|
148
146
|
C: (f, a) => f(...a)
|
|
149
147
|
});
|
|
@@ -156,13 +154,13 @@ var withMultiClientProvider = ({ numClients = 2, createIdentity, createSpace, on
|
|
|
156
154
|
onSpaceCreated,
|
|
157
155
|
onIdentityCreated,
|
|
158
156
|
onInitialized
|
|
159
|
-
});
|
|
157
|
+
}, context);
|
|
160
158
|
spaceReady.current.wake(space);
|
|
161
159
|
log.info("inviting", {
|
|
162
160
|
index
|
|
163
161
|
}, {
|
|
164
162
|
F: __dxlog_file,
|
|
165
|
-
L:
|
|
163
|
+
L: 146,
|
|
166
164
|
S: void 0,
|
|
167
165
|
C: (f, a) => f(...a)
|
|
168
166
|
});
|
|
@@ -170,14 +168,14 @@ var withMultiClientProvider = ({ numClients = 2, createIdentity, createSpace, on
|
|
|
170
168
|
await initializeClient(client, {
|
|
171
169
|
createIdentity,
|
|
172
170
|
onInitialized
|
|
173
|
-
});
|
|
171
|
+
}, context);
|
|
174
172
|
const space = await spaceReady.current.wait();
|
|
175
173
|
if (space) {
|
|
176
174
|
log.info("joining", {
|
|
177
175
|
index
|
|
178
176
|
}, {
|
|
179
177
|
F: __dxlog_file,
|
|
180
|
-
L:
|
|
178
|
+
L: 151,
|
|
181
179
|
S: void 0,
|
|
182
180
|
C: (f, a) => f(...a)
|
|
183
181
|
});
|
|
@@ -241,8 +239,9 @@ var ErrorFallback = ({ error }) => {
|
|
|
241
239
|
};
|
|
242
240
|
export {
|
|
243
241
|
ClientRepeater,
|
|
242
|
+
ClientStory,
|
|
243
|
+
useClientProvider,
|
|
244
244
|
useMultiClient,
|
|
245
|
-
useStoryClientData,
|
|
246
245
|
withClientProvider,
|
|
247
246
|
withMultiClientProvider
|
|
248
247
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/testing/index.ts", "../../../../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 './ClientRepeater';\nexport * from './withClientProvider';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport React, { useState, type FC, useEffect, useRef } from 'react';\n\nimport { Client, type PublicKey } from '@dxos/client';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { type AbstractTypedObject } from '@dxos/echo-schema';\nimport { registerSignalsRuntime } from '@dxos/echo-signals/react';\nimport { faker } from '@dxos/random';\n\nimport { type WithClientProviderProps } from './withClientProvider';\nimport { ClientProvider } from '../client';\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?: AbstractTypedObject[];\n args?: Omit<P, 'id' | 'count'>;\n} & Pick<WithClientProviderProps, 'createIdentity' | 'createSpace' | 'onSpaceCreated'>;\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 onSpaceCreated,\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 useEffect(() => {\n const timeout = setTimeout(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 onSpaceCreated?.({ client, space });\n await Promise.all(\n clients.slice(1).flatMap((client) => performInvitation({ host: space, guest: client.spaces })),\n );\n }\n\n setClients(clients);\n });\n\n return () => clearTimeout(timeout);\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 } from '@storybook/react';\nimport React, { createContext, type PropsWithChildren, useContext, useEffect, useRef, useState } from 'react';\nimport { type FallbackProps, ErrorBoundary as NativeErrorBoundary } from 'react-error-boundary';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { performInvitation, TestBuilder } from '@dxos/client/testing';\nimport { raise } from '@dxos/debug';\nimport { log } from '@dxos/log';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { ClientProvider, type ClientProviderProps } from '../client';\n\ntype InitializeProps = {\n createIdentity?: boolean;\n createSpace?: boolean;\n onInitialized?: (client: Client) => MaybePromise<Record<string, any> | void>;\n onIdentityCreated?: (props: { client: Client }) => MaybePromise<Record<string, any> | void>;\n onSpaceCreated?: (props: { client: Client; space: Space }) => MaybePromise<Record<string, any> | void>;\n};\n\n/**\n * Initialize client, identity and first space.\n */\nconst initializeClient = async (\n client: Client,\n { createIdentity, createSpace, onSpaceCreated, onIdentityCreated, onInitialized }: InitializeProps,\n): Promise<StoryClientProps> => {\n const clientData = await onInitialized?.(client);\n\n let identityData: Record<string, any> | void = {};\n if (createIdentity || createSpace) {\n if (!client.halo.identity.get()) {\n await client.halo.createIdentity();\n identityData = await onIdentityCreated?.({ client });\n }\n }\n\n let space: Space | undefined;\n let spaceData: Record<string, any> | void = {};\n if (createSpace) {\n space = await client.spaces.create({ name: 'Test Space' });\n spaceData = await onSpaceCreated?.({ client, space });\n }\n\n return { space, ...clientData, ...identityData, ...spaceData };\n};\n\ntype StoryClientProps<T extends Record<string, any> = Record<string, unknown>> = T & { space?: Space };\n\n// TODO(wittjosiah): Add to multi-client as well.\nconst StoryClientContext = createContext<StoryClientProps | undefined>(undefined);\n\nexport const useStoryClientData = <T extends Record<string, any> = Record<string, unknown>>() => {\n const data = useContext(StoryClientContext) ?? raise(new Error('Missing withClientProvider decorator.'));\n return data as StoryClientProps<T>;\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 onSpaceCreated,\n onIdentityCreated,\n onInitialized,\n ...props\n}: WithClientProviderProps = {}): Decorator => {\n return (Story) => {\n const [data, setData] = useState<StoryClientProps>({});\n\n const handleInitialized = async (client: Client) => {\n setData(\n await initializeClient(client, {\n createIdentity,\n createSpace,\n onSpaceCreated,\n onIdentityCreated,\n onInitialized,\n }),\n );\n };\n\n return (\n <ErrorBoundary>\n <ClientProvider onInitialized={handleInitialized} {...props}>\n <StoryClientContext.Provider value={data}>\n <Story />\n </StoryClientContext.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 * NOTE: Should come before withLayout.\n */\nexport const withMultiClientProvider = ({\n numClients = 2,\n createIdentity,\n createSpace,\n onSpaceCreated,\n onIdentityCreated,\n onInitialized,\n ...props\n}: WithMultiClientProviderProps): Decorator => {\n return (Story) => {\n const builder = useRef(new TestBuilder());\n const hostRef = useRef<Client>();\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(client, {\n createIdentity,\n createSpace,\n onSpaceCreated,\n onIdentityCreated,\n onInitialized,\n });\n spaceReady.current.wake(space);\n log.info('inviting', { index });\n } else {\n await initializeClient(client, { createIdentity, onInitialized });\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 <NativeErrorBoundary FallbackComponent={ErrorFallback}>{children}</NativeErrorBoundary>;\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": ";;;;;;AAIA,cAAc;;;ACAd,
|
|
6
|
-
"names": ["React", "useState", "useEffect", "useRef", "Client", "TestBuilder", "performInvitation", "registerSignalsRuntime", "faker", "ClientRepeater", "props", "component", "Component", "controls", "Controls", "count", "types", "createIdentity", "createSpace", "onSpaceCreated", "useEffect", "registerSignalsRuntime", "clients", "setClients", "useState", "spaceKey", "setSpaceKey", "testBuilder", "useRef", "TestBuilder", "timeout", "setTimeout", "Array", "map", "_", "Client", "services", "current", "createLocalClientServices", "Promise", "all", "client", "initialize", "halo", "space", "spaces", "create", "name", "faker", "commerce", "productName", "key", "slice", "flatMap", "performInvitation", "host", "guest", "clearTimeout", "length", "index", "ClientProvider", "id", "args", "React", "createContext", "useContext", "useEffect", "useRef", "useState", "ErrorBoundary", "NativeErrorBoundary", "Trigger", "performInvitation", "TestBuilder", "
|
|
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, { useState, type FC, useEffect, useRef } from 'react';\n\nimport { Client, type PublicKey } from '@dxos/client';\nimport { TestBuilder, performInvitation } from '@dxos/client/testing';\nimport { type TypedObject } from '@dxos/echo-schema';\nimport { registerSignalsRuntime } from '@dxos/echo-signals/react';\nimport { faker } from '@dxos/random';\n\nimport { type WithClientProviderProps } from './withClientProvider';\nimport { ClientProvider } from '../client';\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' | 'onSpaceCreated'>;\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 onSpaceCreated,\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 useEffect(() => {\n const timeout = setTimeout(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 onSpaceCreated?.({ client, space }, {});\n await Promise.all(\n clients.slice(1).flatMap((client) => performInvitation({ host: space, guest: client.spaces })),\n );\n }\n\n setClients(clients);\n });\n\n return () => clearTimeout(timeout);\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 StoryContext, type Decorator } from '@storybook/react';\nimport React, { createContext, type PropsWithChildren, useContext, useEffect, useRef, useState } from 'react';\nimport { type FallbackProps, ErrorBoundary as NativeErrorBoundary } from 'react-error-boundary';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { performInvitation, TestBuilder } from '@dxos/client/testing';\nimport { log } from '@dxos/log';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { ClientStory } from './context';\nimport { ClientProvider, type ClientProviderProps } from '../client';\n\ntype InitializeProps = {\n createIdentity?: boolean;\n createSpace?: boolean;\n onInitialized?: (client: Client) => MaybePromise<void>;\n onIdentityCreated?: (props: { client: Client }) => MaybePromise<void>;\n // NOTE: context must be untyped until ClientRepeater is removed.\n onSpaceCreated?: (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, onSpaceCreated, onIdentityCreated, 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 onIdentityCreated?.({ client });\n }\n }\n\n let space: Space | undefined;\n if (createSpace) {\n space = await client.spaces.create({ name: 'Test Space' });\n await onSpaceCreated?.({ 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 onSpaceCreated,\n onIdentityCreated,\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 onSpaceCreated,\n onIdentityCreated,\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 * NOTE: Should come before withLayout.\n */\nexport const withMultiClientProvider = ({\n numClients = 2,\n createIdentity,\n createSpace,\n onSpaceCreated,\n onIdentityCreated,\n onInitialized,\n ...props\n}: WithMultiClientProviderProps): Decorator => {\n return (Story, context) => {\n const builder = useRef(new TestBuilder());\n const hostRef = useRef<Client>();\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 onSpaceCreated,\n onIdentityCreated,\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 <NativeErrorBoundary FallbackComponent={ErrorFallback}>{children}</NativeErrorBoundary>;\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": "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",
|
|
6
|
+
"names": ["createContext", "useContext", "raise", "ClientStory", "createContext", "undefined", "useClientProvider", "useContext", "raise", "Error", "React", "useState", "useEffect", "useRef", "Client", "TestBuilder", "performInvitation", "registerSignalsRuntime", "faker", "ClientRepeater", "props", "component", "Component", "controls", "Controls", "count", "types", "createIdentity", "createSpace", "onSpaceCreated", "useEffect", "registerSignalsRuntime", "clients", "setClients", "useState", "spaceKey", "setSpaceKey", "testBuilder", "useRef", "TestBuilder", "timeout", "setTimeout", "Array", "map", "_", "Client", "services", "current", "createLocalClientServices", "Promise", "all", "client", "initialize", "halo", "space", "spaces", "create", "name", "faker", "commerce", "productName", "key", "slice", "flatMap", "performInvitation", "host", "guest", "clearTimeout", "length", "index", "ClientProvider", "id", "args", "React", "createContext", "useContext", "useEffect", "useRef", "useState", "ErrorBoundary", "NativeErrorBoundary", "Trigger", "performInvitation", "TestBuilder", "log", "initializeClient", "client", "createIdentity", "createSpace", "onSpaceCreated", "onIdentityCreated", "onInitialized", "context", "halo", "identity", "get", "space", "spaces", "create", "name", "withClientProvider", "props", "Story", "data", "setData", "useState", "handleInitialized", "React", "ErrorBoundary", "ClientProvider", "ClientStory", "Provider", "value", "MultiClientContext", "createContext", "id", "useMultiClient", "useContext", "withMultiClientProvider", "numClients", "builder", "useRef", "TestBuilder", "hostRef", "spaceReady", "Trigger", "index", "log", "info", "current", "wake", "wait", "Promise", "all", "performInvitation", "host", "guest", "Array", "from", "length", "map", "_", "key", "services", "createLocalClientServices", "children", "error", "setError", "useEffect", "handleError", "event", "reason", "window", "addEventListener", "removeEventListener", "ErrorFallback", "resetErrorBoundary", "undefined", "NativeErrorBoundary", "FallbackComponent", "message", "stack", "Error", "String", "div", "role", "className", "h1", "pre"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/ClientProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAIvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,sBAAsB,EAAgB,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAyB,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErF,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAGnE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,UAAU,CAAC,GAC1E,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAClC,iBAAiB,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5C;;;;OAIG;IAEH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5C;;;;OAIG;IAEH,QAAQ,CAAC,EAAE,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAEhG;;OAEG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAE1D;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CACxD,CAAC,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,cAAc;IAjDvB;;;;OAIG;aACM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3C;;;;OAIG;aAEM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3C;;;;OAIG;eAEQ,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAE/F;;OAEG;eACQ,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEzD;;;OAGG;qBACc,OAAO;IAExB;;OAEG;eACQ,OAAO;IAElB;;OAEG;oBACa,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC;;;
|
|
1
|
+
{"version":3,"file":"ClientProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/ClientProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAIvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,sBAAsB,EAAgB,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAyB,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErF,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAGnE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,UAAU,CAAC,GAC1E,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAClC,iBAAiB,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5C;;;;OAIG;IAEH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5C;;;;OAIG;IAEH,QAAQ,CAAC,EAAE,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAEhG;;OAEG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAE1D;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CACxD,CAAC,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,cAAc;IAjDvB;;;;OAIG;aACM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3C;;;;OAIG;aAEM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3C;;;;OAIG;eAEQ,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAE/F;;OAEG;eACQ,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEzD;;;OAGG;qBACc,OAAO;IAExB;;OAEG;eACQ,OAAO;IAElB;;OAEG;oBACa,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC;;;4CAwHzD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStream.d.ts","sourceRoot":"","sources":["../../../../src/devtools/useStream.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useStream.d.ts","sourceRoot":"","sources":["../../../../src/devtools/useStream.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,iBAAiB,MAAM,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAQ,cAAc,KAAQ,CAmBzG,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type FC } from 'react';
|
|
2
2
|
import { Client, type PublicKey } from '@dxos/client';
|
|
3
|
-
import { type
|
|
3
|
+
import { type TypedObject } from '@dxos/echo-schema';
|
|
4
4
|
import { type WithClientProviderProps } from './withClientProvider';
|
|
5
5
|
export type ClientRepeatedComponentProps = {
|
|
6
6
|
id: number;
|
|
@@ -16,7 +16,7 @@ export type ClientRepeaterProps<P extends ClientRepeatedComponentProps> = {
|
|
|
16
16
|
controls?: FC<ClientRepeaterControlsProps>;
|
|
17
17
|
count?: number;
|
|
18
18
|
clients?: Client[];
|
|
19
|
-
types?:
|
|
19
|
+
types?: TypedObject[];
|
|
20
20
|
args?: Omit<P, 'id' | 'count'>;
|
|
21
21
|
} & Pick<WithClientProviderProps, 'createIdentity' | 'createSpace' | 'onSpaceCreated'>;
|
|
22
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientRepeater.d.ts","sourceRoot":"","sources":["../../../../src/testing/ClientRepeater.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAY,KAAK,EAAE,EAAqB,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"ClientRepeater.d.ts","sourceRoot":"","sources":["../../../../src/testing/ClientRepeater.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAY,KAAK,EAAE,EAAqB,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGpE,MAAM,MAAM,4BAA4B,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/F,MAAM,MAAM,2BAA2B,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAGhE,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,4BAA4B,IAAI;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,EAAE,CAAC,4BAA4B,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,CAAC,2BAA2B,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC;CAChC,GAAG,IAAI,CAAC,uBAAuB,EAAE,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;AAEvF;;;;GAIG;AAMH,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,4BAA4B,SAAS,mBAAmB,CAAC,CAAC,CAAC,6BA2DnG,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Space } from '@dxos/client/echo';
|
|
2
|
+
export type ClientStory = {
|
|
3
|
+
space?: Space;
|
|
4
|
+
};
|
|
5
|
+
export declare const ClientStory: import("react").Context<ClientStory | undefined>;
|
|
6
|
+
export declare const useClientProvider: () => ClientStory;
|
|
7
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/testing/context.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAGF,eAAO,MAAM,WAAW,kDAAoD,CAAC;AAE7E,eAAO,MAAM,iBAAiB,QAAO,WAEpC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/testing/index.ts"],"names":[],"mappings":"AAIA,cAAc,sBAAsB,CAAC;AAErC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/testing/index.ts"],"names":[],"mappings":"AAIA,cAAc,sBAAsB,CAAC;AAErC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Decorator } from '@storybook/react';
|
|
1
|
+
import { type StoryContext, type Decorator } from '@storybook/react';
|
|
2
2
|
import { type Client } from '@dxos/client';
|
|
3
3
|
import { type Space } from '@dxos/client/echo';
|
|
4
4
|
import { type MaybePromise } from '@dxos/util';
|
|
@@ -6,19 +6,15 @@ import { type ClientProviderProps } from '../client';
|
|
|
6
6
|
type InitializeProps = {
|
|
7
7
|
createIdentity?: boolean;
|
|
8
8
|
createSpace?: boolean;
|
|
9
|
-
onInitialized?: (client: Client) => MaybePromise<
|
|
9
|
+
onInitialized?: (client: Client) => MaybePromise<void>;
|
|
10
10
|
onIdentityCreated?: (props: {
|
|
11
11
|
client: Client;
|
|
12
|
-
}) => MaybePromise<
|
|
12
|
+
}) => MaybePromise<void>;
|
|
13
13
|
onSpaceCreated?: (props: {
|
|
14
14
|
client: Client;
|
|
15
15
|
space: Space;
|
|
16
|
-
}) => MaybePromise<
|
|
16
|
+
}, context: StoryContext | any) => MaybePromise<void>;
|
|
17
17
|
};
|
|
18
|
-
type StoryClientProps<T extends Record<string, any> = Record<string, unknown>> = T & {
|
|
19
|
-
space?: Space;
|
|
20
|
-
};
|
|
21
|
-
export declare const useStoryClientData: <T extends Record<string, any> = Record<string, unknown>>() => StoryClientProps<T>;
|
|
22
18
|
export type WithClientProviderProps = InitializeProps & Omit<ClientProviderProps, 'onInitialized'>;
|
|
23
19
|
/**
|
|
24
20
|
* Decorator that provides the client context.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withClientProvider.d.ts","sourceRoot":"","sources":["../../../../src/testing/withClientProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"withClientProvider.d.ts","sourceRoot":"","sources":["../../../../src/testing/withClientProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAKrE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErE,KAAK,eAAe,GAAG;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAEtE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,EAAE,OAAO,EAAE,YAAY,GAAG,GAAG,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CAC/G,CAAC;AA4BF,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;AAEnG;;GAEG;AACH,eAAO,MAAM,kBAAkB,iGAO5B,uBAAuB,KAAQ,SA6BjC,CAAC;AAKF,MAAM,MAAM,4BAA4B,GAAG,eAAe,GACxD,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAIvE,eAAO,MAAM,cAAc;QAFoB,MAAM;CAEa,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,4GAQjC,4BAA4B,KAAG,SAsDjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"5.7.2"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-client",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5-labs.5f04cf6",
|
|
4
4
|
"description": "React client API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -77,40 +77,40 @@
|
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"react-error-boundary": "^4.0.13",
|
|
80
|
-
"@dxos/async": "0.7.
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/debug": "0.7.
|
|
84
|
-
"@dxos/echo-schema": "0.7.
|
|
85
|
-
"@dxos/
|
|
86
|
-
"@dxos/
|
|
87
|
-
"@dxos/
|
|
88
|
-
"@dxos/
|
|
89
|
-
"@dxos/
|
|
90
|
-
"@dxos/protocols": "0.7.
|
|
91
|
-
"@dxos/
|
|
92
|
-
"@dxos/
|
|
80
|
+
"@dxos/async": "0.7.5-labs.5f04cf6",
|
|
81
|
+
"@dxos/codec-protobuf": "0.7.5-labs.5f04cf6",
|
|
82
|
+
"@dxos/config": "0.7.5-labs.5f04cf6",
|
|
83
|
+
"@dxos/debug": "0.7.5-labs.5f04cf6",
|
|
84
|
+
"@dxos/echo-schema": "0.7.5-labs.5f04cf6",
|
|
85
|
+
"@dxos/client": "0.7.5-labs.5f04cf6",
|
|
86
|
+
"@dxos/invariant": "0.7.5-labs.5f04cf6",
|
|
87
|
+
"@dxos/log": "0.7.5-labs.5f04cf6",
|
|
88
|
+
"@dxos/echo-signals": "0.7.5-labs.5f04cf6",
|
|
89
|
+
"@dxos/node-std": "0.7.5-labs.5f04cf6",
|
|
90
|
+
"@dxos/protocols": "0.7.5-labs.5f04cf6",
|
|
91
|
+
"@dxos/util": "0.7.5-labs.5f04cf6",
|
|
92
|
+
"@dxos/react-hooks": "0.7.5-labs.5f04cf6"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/react": "~18.2.0",
|
|
96
96
|
"@types/react-dom": "~18.2.0",
|
|
97
97
|
"react": "~18.2.0",
|
|
98
98
|
"react-dom": "~18.2.0",
|
|
99
|
-
"@dxos/
|
|
100
|
-
"@dxos/
|
|
101
|
-
"@dxos/
|
|
102
|
-
"@dxos/react-ui
|
|
103
|
-
"@dxos/
|
|
104
|
-
"@dxos/
|
|
99
|
+
"@dxos/random": "0.7.5-labs.5f04cf6",
|
|
100
|
+
"@dxos/storybook-utils": "0.7.5-labs.5f04cf6",
|
|
101
|
+
"@dxos/react-ui-theme": "0.7.5-labs.5f04cf6",
|
|
102
|
+
"@dxos/react-ui": "0.7.5-labs.5f04cf6",
|
|
103
|
+
"@dxos/react-ui-syntax-highlighter": "0.7.5-labs.5f04cf6",
|
|
104
|
+
"@dxos/test-utils": "0.7.5-labs.5f04cf6"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
107
|
"react": "~18.2.0",
|
|
108
108
|
"react-dom": "~18.2.0"
|
|
109
109
|
},
|
|
110
110
|
"optionalDependencies": {
|
|
111
|
-
"@dxos/
|
|
112
|
-
"@dxos/
|
|
113
|
-
"@dxos/react-ui-theme": "0.7.
|
|
111
|
+
"@dxos/react-ui": "0.7.5-labs.5f04cf6",
|
|
112
|
+
"@dxos/random": "0.7.5-labs.5f04cf6",
|
|
113
|
+
"@dxos/react-ui-theme": "0.7.5-labs.5f04cf6"
|
|
114
114
|
},
|
|
115
115
|
"publishConfig": {
|
|
116
116
|
"access": "public"
|
|
@@ -126,9 +126,14 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
126
126
|
|
|
127
127
|
// Create and/or initialize client.
|
|
128
128
|
useEffect(() => {
|
|
129
|
+
let disposed = false;
|
|
129
130
|
const initialize = async (client: Client) => {
|
|
130
131
|
if (!client.initialized) {
|
|
131
|
-
await client.initialize().catch(
|
|
132
|
+
await client.initialize().catch((err) => {
|
|
133
|
+
if (!disposed) {
|
|
134
|
+
setError(err);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
132
137
|
log('client ready');
|
|
133
138
|
await onInitialized?.(client);
|
|
134
139
|
log('initialization complete');
|
|
@@ -143,24 +148,31 @@ export const ClientProvider = forwardRef<Client | undefined, ClientProviderProps
|
|
|
143
148
|
|
|
144
149
|
let client: Client;
|
|
145
150
|
const t = setTimeout(async () => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
try {
|
|
152
|
+
if (clientProvider) {
|
|
153
|
+
// Asynchronously request client.
|
|
154
|
+
client = await getAsyncProviderValue(clientProvider);
|
|
155
|
+
await initialize(client);
|
|
156
|
+
} else {
|
|
157
|
+
// Asynchronously construct client (config may be undefined).
|
|
158
|
+
const config = await getAsyncProviderValue(configProvider);
|
|
159
|
+
log('resolved config', { config });
|
|
160
|
+
const services = await getAsyncProviderValue(servicesProvider, config);
|
|
161
|
+
log('created services', { services });
|
|
162
|
+
client = new Client({ config, services, ...options });
|
|
163
|
+
log('created client');
|
|
164
|
+
await initialize(client);
|
|
165
|
+
}
|
|
166
|
+
} catch (err) {
|
|
167
|
+
if (!disposed) {
|
|
168
|
+
log.catch(err);
|
|
169
|
+
}
|
|
159
170
|
}
|
|
160
171
|
});
|
|
161
172
|
|
|
162
173
|
return () => {
|
|
163
174
|
log('clean up');
|
|
175
|
+
disposed = true;
|
|
164
176
|
clearTimeout(t);
|
|
165
177
|
void client
|
|
166
178
|
?.destroy()
|
|
@@ -6,7 +6,7 @@ import React, { useState, type FC, useEffect, useRef } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Client, type PublicKey } from '@dxos/client';
|
|
8
8
|
import { TestBuilder, performInvitation } from '@dxos/client/testing';
|
|
9
|
-
import { type
|
|
9
|
+
import { type TypedObject } from '@dxos/echo-schema';
|
|
10
10
|
import { registerSignalsRuntime } from '@dxos/echo-signals/react';
|
|
11
11
|
import { faker } from '@dxos/random';
|
|
12
12
|
|
|
@@ -24,7 +24,7 @@ export type ClientRepeaterProps<P extends ClientRepeatedComponentProps> = {
|
|
|
24
24
|
controls?: FC<ClientRepeaterControlsProps>;
|
|
25
25
|
count?: number;
|
|
26
26
|
clients?: Client[];
|
|
27
|
-
types?:
|
|
27
|
+
types?: TypedObject[];
|
|
28
28
|
args?: Omit<P, 'id' | 'count'>;
|
|
29
29
|
} & Pick<WithClientProviderProps, 'createIdentity' | 'createSpace' | 'onSpaceCreated'>;
|
|
30
30
|
|
|
@@ -71,7 +71,7 @@ export const ClientRepeater = <P extends ClientRepeatedComponentProps>(props: Cl
|
|
|
71
71
|
const client = clients[0];
|
|
72
72
|
const space = await client.spaces.create({ name: faker.commerce.productName() });
|
|
73
73
|
setSpaceKey(space.key);
|
|
74
|
-
await onSpaceCreated?.({ client, space });
|
|
74
|
+
await onSpaceCreated?.({ client, space }, {});
|
|
75
75
|
await Promise.all(
|
|
76
76
|
clients.slice(1).flatMap((client) => performInvitation({ host: space, guest: client.spaces })),
|
|
77
77
|
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { createContext, useContext } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type Space } from '@dxos/client/echo';
|
|
8
|
+
import { raise } from '@dxos/debug';
|
|
9
|
+
|
|
10
|
+
export type ClientStory = {
|
|
11
|
+
space?: Space;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// TODO(wittjosiah): Add to multi-client as well.
|
|
15
|
+
export const ClientStory = createContext<ClientStory | undefined>(undefined);
|
|
16
|
+
|
|
17
|
+
export const useClientProvider = (): ClientStory => {
|
|
18
|
+
return useContext(ClientStory) ?? raise(new Error('Missing ClientStory'));
|
|
19
|
+
};
|