@microsoft/live-share-react 1.0.0-preview.9 → 1.0.1-preview.1
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/README.md +99 -35
- package/bin/index.d.ts +6 -6
- package/bin/index.js +6 -6
- package/bin/interfaces/LiveInterfaceExtensions.d.ts +25 -8
- package/bin/interfaces/LiveInterfaceExtensions.d.ts.map +1 -1
- package/bin/interfaces/LiveInterfaceExtensions.js +5 -5
- package/bin/interfaces/index.d.ts +1 -1
- package/bin/interfaces/index.js +1 -1
- package/bin/internal/errors.d.ts +26 -0
- package/bin/internal/errors.d.ts.map +1 -0
- package/bin/internal/errors.js +39 -0
- package/bin/internal/errors.js.map +1 -0
- package/bin/internal/index.d.ts +4 -0
- package/bin/internal/index.d.ts.map +1 -0
- package/bin/internal/index.js +4 -0
- package/bin/internal/index.js.map +1 -0
- package/bin/internal/type-guards.d.ts +6 -0
- package/bin/internal/type-guards.d.ts.map +1 -0
- package/bin/internal/type-guards.js +8 -0
- package/bin/internal/type-guards.js.map +1 -0
- package/bin/{internal-hooks → internal}/useSharedStateRegistry.d.ts +30 -30
- package/bin/internal/useSharedStateRegistry.d.ts.map +1 -0
- package/bin/{internal-hooks → internal}/useSharedStateRegistry.js +101 -99
- package/bin/internal/useSharedStateRegistry.js.map +1 -0
- package/bin/live-hooks/index.d.ts +6 -6
- package/bin/live-hooks/index.js +6 -6
- package/bin/live-hooks/useLiveCanvas.d.ts +27 -27
- package/bin/live-hooks/useLiveCanvas.d.ts.map +1 -1
- package/bin/live-hooks/useLiveCanvas.js +158 -166
- package/bin/live-hooks/useLiveCanvas.js.map +1 -1
- package/bin/live-hooks/useLiveEvent.d.ts +21 -21
- package/bin/live-hooks/useLiveEvent.d.ts.map +1 -1
- package/bin/live-hooks/useLiveEvent.js +100 -85
- package/bin/live-hooks/useLiveEvent.js.map +1 -1
- package/bin/live-hooks/useLivePresence.d.ts +25 -25
- package/bin/live-hooks/useLivePresence.d.ts.map +1 -1
- package/bin/live-hooks/useLivePresence.js +106 -92
- package/bin/live-hooks/useLivePresence.js.map +1 -1
- package/bin/live-hooks/useLiveState.d.ts +19 -19
- package/bin/live-hooks/useLiveState.d.ts.map +1 -1
- package/bin/live-hooks/useLiveState.js +79 -70
- package/bin/live-hooks/useLiveState.js.map +1 -1
- package/bin/live-hooks/useLiveTimer.d.ts +7 -7
- package/bin/live-hooks/useLiveTimer.d.ts.map +1 -1
- package/bin/live-hooks/useLiveTimer.js +150 -131
- package/bin/live-hooks/useLiveTimer.js.map +1 -1
- package/bin/live-hooks/useMediaSynchronizer.d.ts +22 -22
- package/bin/live-hooks/useMediaSynchronizer.d.ts.map +1 -1
- package/bin/live-hooks/useMediaSynchronizer.js +206 -161
- package/bin/live-hooks/useMediaSynchronizer.js.map +1 -1
- package/bin/providers/AzureProvider.d.ts +33 -33
- package/bin/providers/AzureProvider.d.ts.map +1 -1
- package/bin/providers/AzureProvider.js +101 -101
- package/bin/providers/AzureProvider.js.map +1 -1
- package/bin/providers/LiveShareProvider.d.ts +62 -41
- package/bin/providers/LiveShareProvider.d.ts.map +1 -1
- package/bin/providers/LiveShareProvider.js +68 -65
- package/bin/providers/LiveShareProvider.js.map +1 -1
- package/bin/providers/index.d.ts +2 -2
- package/bin/providers/index.js +2 -2
- package/bin/shared-hooks/index.d.ts +3 -4
- package/bin/shared-hooks/index.d.ts.map +1 -1
- package/bin/shared-hooks/index.js +3 -4
- package/bin/shared-hooks/index.js.map +1 -1
- package/bin/shared-hooks/useDynamicDDS.d.ts +18 -18
- package/bin/shared-hooks/useDynamicDDS.d.ts.map +1 -1
- package/bin/shared-hooks/useDynamicDDS.js +67 -67
- package/bin/shared-hooks/useDynamicDDS.js.map +1 -1
- package/bin/shared-hooks/useSharedMap.d.ts +21 -21
- package/bin/shared-hooks/useSharedMap.d.ts.map +1 -1
- package/bin/shared-hooks/useSharedMap.js +112 -105
- package/bin/shared-hooks/useSharedMap.js.map +1 -1
- package/bin/shared-hooks/useSharedState.d.ts +20 -20
- package/bin/shared-hooks/useSharedState.d.ts.map +1 -1
- package/bin/shared-hooks/useSharedState.js +72 -62
- package/bin/shared-hooks/useSharedState.js.map +1 -1
- package/bin/types/ActionTypes.d.ts +111 -29
- package/bin/types/ActionTypes.d.ts.map +1 -1
- package/bin/types/ActionTypes.js +5 -5
- package/bin/types/PropTypes.d.ts +7 -7
- package/bin/types/PropTypes.d.ts.map +1 -1
- package/bin/types/PropTypes.js +5 -5
- package/bin/types/ResultTypes.d.ts +174 -162
- package/bin/types/ResultTypes.d.ts.map +1 -1
- package/bin/types/ResultTypes.js +5 -5
- package/bin/types/index.d.ts +3 -3
- package/bin/types/index.js +3 -3
- package/bin/utils/index.d.ts +1 -1
- package/bin/utils/index.js +1 -1
- package/bin/utils/type-check.d.ts +14 -14
- package/bin/utils/type-check.js +53 -53
- package/package.json +18 -14
- package/src/interfaces/LiveInterfaceExtensions.ts +19 -2
- package/src/internal/errors.ts +48 -0
- package/src/internal/index.ts +3 -0
- package/src/internal/type-guards.ts +9 -0
- package/src/{internal-hooks → internal}/useSharedStateRegistry.ts +6 -5
- package/src/live-hooks/useLiveCanvas.ts +12 -20
- package/src/live-hooks/useLiveEvent.ts +41 -22
- package/src/live-hooks/useLivePresence.ts +52 -33
- package/src/live-hooks/useLiveState.ts +48 -53
- package/src/live-hooks/useLiveTimer.ts +50 -41
- package/src/live-hooks/useMediaSynchronizer.ts +108 -41
- package/src/providers/AzureProvider.tsx +3 -8
- package/src/providers/LiveShareProvider.tsx +46 -16
- package/src/shared-hooks/index.ts +0 -1
- package/src/shared-hooks/useDynamicDDS.ts +15 -8
- package/src/shared-hooks/useSharedMap.ts +48 -22
- package/src/shared-hooks/useSharedState.ts +15 -5
- package/src/types/ActionTypes.ts +100 -15
- package/src/types/ResultTypes.ts +23 -9
- package/bin/internal-hooks/index.d.ts +0 -2
- package/bin/internal-hooks/index.d.ts.map +0 -1
- package/bin/internal-hooks/index.js +0 -2
- package/bin/internal-hooks/index.js.map +0 -1
- package/bin/internal-hooks/useDynamicDDSRegistry.d.ts +0 -14
- package/bin/internal-hooks/useDynamicDDSRegistry.d.ts.map +0 -1
- package/bin/internal-hooks/useDynamicDDSRegistry.js +0 -142
- package/bin/internal-hooks/useDynamicDDSRegistry.js.map +0 -1
- package/bin/internal-hooks/useSharedStateRegistry.d.ts.map +0 -1
- package/bin/internal-hooks/useSharedStateRegistry.js.map +0 -1
- package/bin/internal-hooks/useStateRef.d.ts +0 -7
- package/bin/internal-hooks/useStateRef.d.ts.map +0 -1
- package/bin/internal-hooks/useStateRef.js +0 -15
- package/bin/internal-hooks/useStateRef.js.map +0 -1
- package/bin/live-hooks/useLiveAICompletion.d.ts +0 -29
- package/bin/live-hooks/useLiveAICompletion.d.ts.map +0 -1
- package/bin/live-hooks/useLiveAICompletion.js +0 -186
- package/bin/live-hooks/useLiveAICompletion.js.map +0 -1
- package/bin/live-hooks/useLiveCoPilot.d.ts +0 -28
- package/bin/live-hooks/useLiveCoPilot.d.ts.map +0 -1
- package/bin/live-hooks/useLiveCoPilot.js +0 -178
- package/bin/live-hooks/useLiveCoPilot.js.map +0 -1
- package/bin/live-share-turbo/AzureTurboClient.d.ts +0 -39
- package/bin/live-share-turbo/AzureTurboClient.d.ts.map +0 -1
- package/bin/live-share-turbo/AzureTurboClient.js +0 -56
- package/bin/live-share-turbo/AzureTurboClient.js.map +0 -1
- package/bin/live-share-turbo/LiveShareTurboClient.d.ts +0 -53
- package/bin/live-share-turbo/LiveShareTurboClient.d.ts.map +0 -1
- package/bin/live-share-turbo/LiveShareTurboClient.js +0 -69
- package/bin/live-share-turbo/LiveShareTurboClient.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboDataObject.d.ts +0 -31
- package/bin/live-share-turbo/dds-objects/TurboDataObject.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboDataObject.js +0 -75
- package/bin/live-share-turbo/dds-objects/TurboDataObject.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.d.ts +0 -48
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.js +0 -104
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.d.ts +0 -28
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.js +0 -68
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.d.ts +0 -60
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.js +0 -111
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.d.ts +0 -77
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.js +0 -137
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveState.d.ts +0 -30
- package/bin/live-share-turbo/dds-objects/TurboLiveState.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboLiveState.js +0 -74
- package/bin/live-share-turbo/dds-objects/TurboLiveState.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.d.ts +0 -61
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.js +0 -108
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.js.map +0 -1
- package/bin/live-share-turbo/dds-objects/index.d.ts +0 -8
- package/bin/live-share-turbo/dds-objects/index.d.ts.map +0 -1
- package/bin/live-share-turbo/dds-objects/index.js +0 -8
- package/bin/live-share-turbo/dds-objects/index.js.map +0 -1
- package/bin/live-share-turbo/index.d.ts +0 -5
- package/bin/live-share-turbo/index.d.ts.map +0 -1
- package/bin/live-share-turbo/index.js +0 -5
- package/bin/live-share-turbo/index.js.map +0 -1
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.d.ts +0 -15
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.d.ts.map +0 -1
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.js +0 -2
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.js.map +0 -1
- package/bin/live-share-turbo/interfaces/index.d.ts +0 -3
- package/bin/live-share-turbo/interfaces/index.d.ts.map +0 -1
- package/bin/live-share-turbo/interfaces/index.js +0 -3
- package/bin/live-share-turbo/interfaces/index.js.map +0 -1
- package/bin/live-share-turbo/internals/FluidTurboClient.d.ts +0 -39
- package/bin/live-share-turbo/internals/FluidTurboClient.d.ts.map +0 -1
- package/bin/live-share-turbo/internals/FluidTurboClient.js +0 -121
- package/bin/live-share-turbo/internals/FluidTurboClient.js.map +0 -1
- package/bin/live-share-turbo/internals/index.d.ts +0 -2
- package/bin/live-share-turbo/internals/index.d.ts.map +0 -1
- package/bin/live-share-turbo/internals/index.js +0 -2
- package/bin/live-share-turbo/internals/index.js.map +0 -1
- package/bin/live-share-turbo/internals/types.d.ts +0 -4
- package/bin/live-share-turbo/internals/types.d.ts.map +0 -1
- package/bin/live-share-turbo/internals/types.js +0 -2
- package/bin/live-share-turbo/internals/types.js.map +0 -1
- package/bin/providers/FluidContextProvider.d.ts +0 -34
- package/bin/providers/FluidContextProvider.d.ts.map +0 -1
- package/bin/providers/FluidContextProvider.js +0 -99
- package/bin/providers/FluidContextProvider.js.map +0 -1
- package/bin/providers/LiveShareContextProvider.d.ts +0 -42
- package/bin/providers/LiveShareContextProvider.d.ts.map +0 -1
- package/bin/providers/LiveShareContextProvider.js +0 -63
- package/bin/providers/LiveShareContextProvider.js.map +0 -1
- package/bin/shared-hooks/useLockedTask.d.ts +0 -11
- package/bin/shared-hooks/useLockedTask.d.ts.map +0 -1
- package/bin/shared-hooks/useLockedTask.js +0 -82
- package/bin/shared-hooks/useLockedTask.js.map +0 -1
- package/bin/shared-hooks/useTaskManager.d.ts +0 -13
- package/bin/shared-hooks/useTaskManager.d.ts.map +0 -1
- package/bin/shared-hooks/useTaskManager.js +0 -86
- package/bin/shared-hooks/useTaskManager.js.map +0 -1
- package/bin/utils/getContainerSchema.d.ts +0 -8
- package/bin/utils/getContainerSchema.d.ts.map +0 -1
- package/bin/utils/getContainerSchema.js +0 -41
- package/bin/utils/getContainerSchema.js.map +0 -1
- package/src/internal-hooks/index.ts +0 -1
- package/src/shared-hooks/useTaskManager.ts +0 -82
- package/tinylicious.log +0 -4
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Licensed under the Microsoft Live Share SDK License.
|
|
4
|
-
*/
|
|
5
|
-
import { ExtendedMediaMetadata, IMediaPlayer } from "@microsoft/live-share-media";
|
|
6
|
-
import React from "react";
|
|
7
|
-
export declare function isRefObject<T>(value: any): value is React.RefObject<T>;
|
|
8
|
-
export declare function isMediaElement(value: any): value is IMediaPlayer;
|
|
9
|
-
export declare function isExtendedMediaMetadata(value: any): value is ExtendedMediaMetadata;
|
|
10
|
-
export declare function isMap(value: any): value is Map<string, any>;
|
|
11
|
-
export declare function isEntries(value: any): value is readonly (readonly [string, any])[];
|
|
12
|
-
export declare function isJSON(value: any): value is {
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
};
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the Microsoft Live Share SDK License.
|
|
4
|
+
*/
|
|
5
|
+
import { ExtendedMediaMetadata, IMediaPlayer } from "@microsoft/live-share-media";
|
|
6
|
+
import React from "react";
|
|
7
|
+
export declare function isRefObject<T>(value: any): value is React.RefObject<T>;
|
|
8
|
+
export declare function isMediaElement(value: any): value is IMediaPlayer;
|
|
9
|
+
export declare function isExtendedMediaMetadata(value: any): value is ExtendedMediaMetadata;
|
|
10
|
+
export declare function isMap(value: any): value is Map<string, any>;
|
|
11
|
+
export declare function isEntries(value: any): value is readonly (readonly [string, any])[];
|
|
12
|
+
export declare function isJSON(value: any): value is {
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
};
|
|
15
15
|
//# sourceMappingURL=type-check.d.ts.map
|
package/bin/utils/type-check.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Licensed under the Microsoft Live Share SDK License.
|
|
4
|
-
*/
|
|
5
|
-
export function isRefObject(value) {
|
|
6
|
-
return value.current === null || !!value.current;
|
|
7
|
-
}
|
|
8
|
-
export function isMediaElement(value) {
|
|
9
|
-
if (value) {
|
|
10
|
-
return (value.currentSrc !== undefined &&
|
|
11
|
-
value.currentTime !== undefined &&
|
|
12
|
-
value.duration !== undefined &&
|
|
13
|
-
value.ended !== undefined &&
|
|
14
|
-
value.muted !== undefined &&
|
|
15
|
-
value.paused !== undefined &&
|
|
16
|
-
value.playbackRate !== undefined &&
|
|
17
|
-
value.src !== undefined &&
|
|
18
|
-
value.volume !== undefined &&
|
|
19
|
-
value.load !== undefined &&
|
|
20
|
-
value.pause !== undefined &&
|
|
21
|
-
value.play !== undefined &&
|
|
22
|
-
value.addEventListener !== undefined &&
|
|
23
|
-
value.removeEventListener !== undefined);
|
|
24
|
-
}
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
export function isExtendedMediaMetadata(value) {
|
|
28
|
-
return value === null || !!(value === null || value === void 0 ? void 0 : value.trackIdentifier);
|
|
29
|
-
}
|
|
30
|
-
export function isMap(value) {
|
|
31
|
-
return value instanceof Map;
|
|
32
|
-
}
|
|
33
|
-
export function isEntries(value) {
|
|
34
|
-
try {
|
|
35
|
-
const tryValue = value;
|
|
36
|
-
if (typeof tryValue[0][0] === "string") {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export function isJSON(value) {
|
|
46
|
-
try {
|
|
47
|
-
const tryValue = value;
|
|
48
|
-
return Object.keys(tryValue).length > 0;
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the Microsoft Live Share SDK License.
|
|
4
|
+
*/
|
|
5
|
+
export function isRefObject(value) {
|
|
6
|
+
return value.current === null || !!value.current;
|
|
7
|
+
}
|
|
8
|
+
export function isMediaElement(value) {
|
|
9
|
+
if (value) {
|
|
10
|
+
return (value.currentSrc !== undefined &&
|
|
11
|
+
value.currentTime !== undefined &&
|
|
12
|
+
value.duration !== undefined &&
|
|
13
|
+
value.ended !== undefined &&
|
|
14
|
+
value.muted !== undefined &&
|
|
15
|
+
value.paused !== undefined &&
|
|
16
|
+
value.playbackRate !== undefined &&
|
|
17
|
+
value.src !== undefined &&
|
|
18
|
+
value.volume !== undefined &&
|
|
19
|
+
value.load !== undefined &&
|
|
20
|
+
value.pause !== undefined &&
|
|
21
|
+
value.play !== undefined &&
|
|
22
|
+
value.addEventListener !== undefined &&
|
|
23
|
+
value.removeEventListener !== undefined);
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
export function isExtendedMediaMetadata(value) {
|
|
28
|
+
return value === null || !!(value === null || value === void 0 ? void 0 : value.trackIdentifier);
|
|
29
|
+
}
|
|
30
|
+
export function isMap(value) {
|
|
31
|
+
return value instanceof Map;
|
|
32
|
+
}
|
|
33
|
+
export function isEntries(value) {
|
|
34
|
+
try {
|
|
35
|
+
const tryValue = value;
|
|
36
|
+
if (typeof tryValue[0][0] === "string") {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function isJSON(value) {
|
|
46
|
+
try {
|
|
47
|
+
const tryValue = value;
|
|
48
|
+
return Object.keys(tryValue).length > 0;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
54
|
//# sourceMappingURL=type-check.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/live-share-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1-preview.1",
|
|
4
4
|
"description": "Build collaborative React apps using Microsoft's Fluid & Live Share frameworks with ease.",
|
|
5
5
|
"author": "Microsoft",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -12,26 +12,30 @@
|
|
|
12
12
|
"typecheck": "tsc"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@
|
|
16
|
-
"@fluid-experimental/task-manager": "~1.2.3",
|
|
17
|
-
"@microsoft/live-share": "1.0.0-preview.9",
|
|
18
|
-
"@microsoft/live-share-canvas": "1.0.0-preview.9",
|
|
19
|
-
"@microsoft/live-share-media": "1.0.0-preview.9",
|
|
20
|
-
"@microsoft/live-share-turbo": "1.0.0-preview.9",
|
|
21
|
-
"fluid-framework": "~1.2.3",
|
|
15
|
+
"@microsoft/live-share-turbo": "1.0.1-preview.1",
|
|
22
16
|
"url": "^0.11.0",
|
|
23
|
-
"uuid": "^
|
|
17
|
+
"uuid": "^9.0.0"
|
|
24
18
|
},
|
|
25
19
|
"devDependencies": {
|
|
26
|
-
"@babel/core": "^7.
|
|
27
|
-
"@fluidframework/
|
|
20
|
+
"@babel/core": "^7.21.8",
|
|
21
|
+
"@fluidframework/azure-client": "^1.1.1",
|
|
22
|
+
"@fluidframework/test-client-utils": "^1.3.6",
|
|
23
|
+
"@microsoft/live-share": "1.0.1",
|
|
24
|
+
"@microsoft/live-share-canvas": "1.0.1",
|
|
25
|
+
"@microsoft/live-share-media": "1.0.1",
|
|
28
26
|
"@types/react": "^18.0.0",
|
|
29
27
|
"@types/react-dom": "^18.0.0",
|
|
30
|
-
"@types/uuid": "^
|
|
31
|
-
"babel-loader": "^
|
|
32
|
-
"
|
|
28
|
+
"@types/uuid": "^9.0.1",
|
|
29
|
+
"babel-loader": "^9.1.2",
|
|
30
|
+
"fluid-framework": "^1.3.6",
|
|
31
|
+
"typescript": "^5.0.4"
|
|
33
32
|
},
|
|
34
33
|
"peerDependencies": {
|
|
34
|
+
"@fluidframework/azure-client": "^1.0.0",
|
|
35
|
+
"@microsoft/live-share": "1.0.1",
|
|
36
|
+
"@microsoft/live-share-canvas": "1.0.1",
|
|
37
|
+
"@microsoft/live-share-media": "1.0.1",
|
|
38
|
+
"fluid-framework": "^1.2.3",
|
|
35
39
|
"react": "^16.8.0 || ^17 || ^18",
|
|
36
40
|
"react-dom": "^16.8.0 || ^17 || ^18"
|
|
37
41
|
},
|
|
@@ -3,7 +3,24 @@
|
|
|
3
3
|
* Licensed under the Microsoft Live Share SDK License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Object response for a received event
|
|
8
|
+
*/
|
|
9
|
+
export interface IReceiveLiveEvent<TEvent = any> {
|
|
10
|
+
/**
|
|
11
|
+
* The value of the event that was sent
|
|
12
|
+
*/
|
|
13
|
+
value: TEvent;
|
|
14
|
+
/**
|
|
15
|
+
* True if the local client was the one to send this event
|
|
16
|
+
*/
|
|
8
17
|
local: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Client ID of the user that sent the event
|
|
20
|
+
*/
|
|
21
|
+
clientId: string;
|
|
22
|
+
/**
|
|
23
|
+
* Server timestamp at which the event was sent
|
|
24
|
+
*/
|
|
25
|
+
timestamp: number;
|
|
9
26
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hidden
|
|
3
|
+
*/
|
|
4
|
+
class UseLiveDataObjectActionError extends Error {
|
|
5
|
+
constructor(ddsName: string, functionName: string, message: string) {
|
|
6
|
+
super(
|
|
7
|
+
`use${toFirstLetterUppercase(ddsName)} ${functionName}: ${message}`
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @hidden
|
|
14
|
+
*/
|
|
15
|
+
export class ActionContainerNotJoinedError extends UseLiveDataObjectActionError {
|
|
16
|
+
constructor(ddsName: string, functionName: string) {
|
|
17
|
+
super(ddsName, functionName, "container has not yet been joined");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @hidden
|
|
23
|
+
*/
|
|
24
|
+
export class ActionLiveDataObjectUndefinedError extends UseLiveDataObjectActionError {
|
|
25
|
+
constructor(ddsName: string, functionName: string) {
|
|
26
|
+
super(
|
|
27
|
+
ddsName,
|
|
28
|
+
functionName,
|
|
29
|
+
`${ddsName} is undefined, which means it is still being dynamically created`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @hidden
|
|
36
|
+
*/
|
|
37
|
+
export class ActionLiveDataObjectInitializedError extends UseLiveDataObjectActionError {
|
|
38
|
+
constructor(ddsName: string, functionName: string) {
|
|
39
|
+
super(ddsName, functionName, `${ddsName} is not initialized`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @hidden
|
|
45
|
+
*/
|
|
46
|
+
function toFirstLetterUppercase(word: string) {
|
|
47
|
+
return word[0].toUpperCase() + word.substring(1);
|
|
48
|
+
}
|
|
@@ -70,9 +70,8 @@ export const useSharedStateRegistry = (
|
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
// Set initial values, if known
|
|
73
|
-
const stateMap = results?.container.initialObjects
|
|
74
|
-
|
|
|
75
|
-
| undefined;
|
|
73
|
+
const stateMap = results?.container.initialObjects
|
|
74
|
+
.TURBO_STATE_MAP as SharedMap | undefined;
|
|
76
75
|
const initialValue = stateMap?.get(uniqueKey);
|
|
77
76
|
if (initialValue) {
|
|
78
77
|
setLocalStateAction(initialValue);
|
|
@@ -102,7 +101,8 @@ export const useSharedStateRegistry = (
|
|
|
102
101
|
(uniqueKey: string, value: any) => {
|
|
103
102
|
if (!results) return;
|
|
104
103
|
const { container } = results;
|
|
105
|
-
const stateMap = container.initialObjects
|
|
104
|
+
const stateMap = container.initialObjects
|
|
105
|
+
.TURBO_STATE_MAP as SharedMap;
|
|
106
106
|
stateMap.set(uniqueKey, value);
|
|
107
107
|
},
|
|
108
108
|
[results]
|
|
@@ -118,7 +118,8 @@ export const useSharedStateRegistry = (
|
|
|
118
118
|
let actionsMap =
|
|
119
119
|
registeredSharedSetStateActionMapRef.current.get(uniqueKey);
|
|
120
120
|
actionsMap?.clear();
|
|
121
|
-
const stateMap = container.initialObjects
|
|
121
|
+
const stateMap = container.initialObjects
|
|
122
|
+
.TURBO_STATE_MAP as SharedMap;
|
|
122
123
|
stateMap.delete(uniqueKey);
|
|
123
124
|
},
|
|
124
125
|
[results]
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
InkingManager,
|
|
10
10
|
InkingTool,
|
|
11
11
|
IPoint,
|
|
12
|
-
IUserInfo,
|
|
13
12
|
LiveCanvas,
|
|
14
13
|
} from "@microsoft/live-share-canvas";
|
|
15
14
|
import React from "react";
|
|
@@ -33,7 +32,7 @@ import { isRefObject } from "../utils";
|
|
|
33
32
|
* @param scale Optional. Stateful scale number to use in the `InkingManager`. Defaults to 1 and must be greater than 0.
|
|
34
33
|
* @param referencePoint Optional. Stateful reference point enum to use in the `InkingManger`. Defaults to "center".
|
|
35
34
|
* @param isCursorShared Optional. Stateful boolean flag for whether cursor should be shared in `LiveCanvas`. Defaults to false.
|
|
36
|
-
* @param
|
|
35
|
+
* @param localUserPictureUrl Optional. url string for the local user to display alongside their cursor. Defaults to undefined.
|
|
37
36
|
* @returns IUseLiveCanvasResults object that contains the `liveCanvas` data object and `inkingManager`.
|
|
38
37
|
*/
|
|
39
38
|
export function useLiveCanvas(
|
|
@@ -46,7 +45,7 @@ export function useLiveCanvas(
|
|
|
46
45
|
scale?: number,
|
|
47
46
|
referencePoint?: CanvasReferencePoint,
|
|
48
47
|
isCursorShared?: boolean,
|
|
49
|
-
|
|
48
|
+
localUserPictureUrl?: string
|
|
50
49
|
): IUseLiveCanvasResults {
|
|
51
50
|
/**
|
|
52
51
|
* User facing: inking manager instance
|
|
@@ -56,7 +55,10 @@ export function useLiveCanvas(
|
|
|
56
55
|
/**
|
|
57
56
|
* User facing: dynamically load the DDS for the given unique key.
|
|
58
57
|
*/
|
|
59
|
-
const { dds: liveCanvas } = useDynamicDDS<LiveCanvas>(
|
|
58
|
+
const { dds: liveCanvas } = useDynamicDDS<LiveCanvas>(
|
|
59
|
+
uniqueKey,
|
|
60
|
+
LiveCanvas
|
|
61
|
+
);
|
|
60
62
|
|
|
61
63
|
/**
|
|
62
64
|
* Setup the InkingManager and LiveCanvas
|
|
@@ -162,31 +164,21 @@ export function useLiveCanvas(
|
|
|
162
164
|
* Sets the isCursorShared of the liveCanvas based on the 'isCursorShared' prop
|
|
163
165
|
*/
|
|
164
166
|
React.useEffect(() => {
|
|
165
|
-
if (
|
|
166
|
-
liveCanvas?.isCursorShared !== undefined &&
|
|
167
|
-
isCursorShared !== undefined
|
|
168
|
-
) {
|
|
167
|
+
if (liveCanvas && isCursorShared !== undefined) {
|
|
169
168
|
liveCanvas.isCursorShared = isCursorShared;
|
|
170
169
|
}
|
|
171
|
-
}, [isCursorShared, liveCanvas
|
|
170
|
+
}, [isCursorShared, liveCanvas]);
|
|
172
171
|
|
|
173
172
|
/**
|
|
174
173
|
* Sets the onGetLocalUserInfo method of the liveCanvas based on the 'localUserCursor' prop
|
|
175
174
|
*/
|
|
176
175
|
React.useEffect(() => {
|
|
177
|
-
if (liveCanvas
|
|
178
|
-
liveCanvas.
|
|
179
|
-
return
|
|
180
|
-
displayName: localUserCursor.displayName,
|
|
181
|
-
pictureUri: localUserCursor.pictureUri,
|
|
182
|
-
};
|
|
176
|
+
if (liveCanvas && localUserPictureUrl) {
|
|
177
|
+
liveCanvas.onGetLocalUserPictureUrl = (): string | undefined => {
|
|
178
|
+
return localUserPictureUrl;
|
|
183
179
|
};
|
|
184
180
|
}
|
|
185
|
-
}, [
|
|
186
|
-
localUserCursor?.displayName,
|
|
187
|
-
localUserCursor?.pictureUri,
|
|
188
|
-
liveCanvas?.onGetLocalUserInfo,
|
|
189
|
-
]);
|
|
181
|
+
}, [localUserPictureUrl, liveCanvas]);
|
|
190
182
|
|
|
191
183
|
/**
|
|
192
184
|
* Return hook response
|
|
@@ -16,6 +16,12 @@ import {
|
|
|
16
16
|
} from "../types";
|
|
17
17
|
import { IReceiveLiveEvent } from "../interfaces";
|
|
18
18
|
import { useDynamicDDS } from "../shared-hooks";
|
|
19
|
+
import {
|
|
20
|
+
ActionContainerNotJoinedError,
|
|
21
|
+
ActionLiveDataObjectInitializedError,
|
|
22
|
+
ActionLiveDataObjectUndefinedError,
|
|
23
|
+
} from "../internal";
|
|
24
|
+
import { useFluidObjectsContext } from "../providers";
|
|
19
25
|
|
|
20
26
|
/**
|
|
21
27
|
* React hook for using a Live Share `LiveEvent`.
|
|
@@ -31,7 +37,7 @@ import { useDynamicDDS } from "../shared-hooks";
|
|
|
31
37
|
* @param onReceivedEvent Optional. Callback method to be called when a new notification is received.
|
|
32
38
|
* @returns stateful `latestEvent` & `allEvents` list, `sendEvent` callback, and the `liveEvent` object.
|
|
33
39
|
*/
|
|
34
|
-
export function useLiveEvent<TEvent
|
|
40
|
+
export function useLiveEvent<TEvent = any>(
|
|
35
41
|
uniqueKey: string,
|
|
36
42
|
allowedRoles?: UserMeetingRole[],
|
|
37
43
|
onReceivedEvent?: OnReceivedLiveEventAction<TEvent>
|
|
@@ -49,49 +55,62 @@ export function useLiveEvent<TEvent extends object = object>(
|
|
|
49
55
|
/**
|
|
50
56
|
* User facing: dynamically load the DDS for the given unique key.
|
|
51
57
|
*/
|
|
52
|
-
const { dds: liveEvent } = useDynamicDDS<LiveEvent
|
|
58
|
+
const { dds: liveEvent } = useDynamicDDS<LiveEvent<TEvent>>(
|
|
59
|
+
uniqueKey,
|
|
60
|
+
LiveEvent<TEvent>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const { container } = useFluidObjectsContext();
|
|
53
64
|
|
|
54
65
|
/**
|
|
55
66
|
* User facing: callback to send event through `LiveEvent`
|
|
56
67
|
*/
|
|
57
68
|
const sendEvent: SendLiveEventAction<TEvent> = React.useCallback(
|
|
58
|
-
(event: TEvent) => {
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
async (event: TEvent) => {
|
|
70
|
+
if (!container) {
|
|
71
|
+
throw new ActionContainerNotJoinedError(
|
|
72
|
+
"liveEvent",
|
|
73
|
+
"sendEvent"
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (liveEvent === undefined) {
|
|
77
|
+
throw new ActionLiveDataObjectUndefinedError(
|
|
78
|
+
"liveEvent",
|
|
79
|
+
"sendEvent"
|
|
64
80
|
);
|
|
65
|
-
return;
|
|
66
81
|
}
|
|
67
82
|
if (!liveEvent.isInitialized) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
83
|
+
throw new ActionLiveDataObjectInitializedError(
|
|
84
|
+
"liveEvent",
|
|
85
|
+
"sendEvent"
|
|
72
86
|
);
|
|
73
|
-
return;
|
|
74
87
|
}
|
|
75
|
-
liveEvent
|
|
88
|
+
return await liveEvent.send(event);
|
|
76
89
|
},
|
|
77
|
-
[liveEvent
|
|
90
|
+
[container, liveEvent]
|
|
78
91
|
);
|
|
79
92
|
|
|
80
93
|
/**
|
|
81
94
|
* Setup change listeners and start `LiveEvent` if needed
|
|
82
95
|
*/
|
|
83
96
|
React.useEffect(() => {
|
|
84
|
-
if (liveEvent?.isInitialized === undefined)
|
|
85
|
-
return;
|
|
97
|
+
if (liveEvent?.isInitialized === undefined) return;
|
|
86
98
|
// Register event listener
|
|
87
|
-
const onEventReceived = (
|
|
99
|
+
const onEventReceived = (
|
|
100
|
+
event: TEvent,
|
|
101
|
+
local: boolean,
|
|
102
|
+
clientId: string,
|
|
103
|
+
timestamp: number
|
|
104
|
+
) => {
|
|
88
105
|
// If developer passed the optional onReceivedEvent callback, we
|
|
89
106
|
// call it.
|
|
90
|
-
onReceivedEvent?.(event
|
|
107
|
+
onReceivedEvent?.(event, local);
|
|
91
108
|
// Set the received event to our local state
|
|
92
109
|
const received: IReceiveLiveEvent<TEvent> = {
|
|
93
|
-
|
|
110
|
+
value: event,
|
|
94
111
|
local,
|
|
112
|
+
clientId,
|
|
113
|
+
timestamp,
|
|
95
114
|
};
|
|
96
115
|
allEventsRef.current = [...allEventsRef.current, received];
|
|
97
116
|
setLatestReceived(received);
|
|
@@ -106,7 +125,7 @@ export function useLiveEvent<TEvent extends object = object>(
|
|
|
106
125
|
// on unmount, remove event listeners
|
|
107
126
|
liveEvent?.off(LiveEventEvents.received, onEventReceived);
|
|
108
127
|
};
|
|
109
|
-
}, [liveEvent
|
|
128
|
+
}, [liveEvent]);
|
|
110
129
|
|
|
111
130
|
return {
|
|
112
131
|
latestEvent,
|
|
@@ -7,10 +7,17 @@ import {
|
|
|
7
7
|
LivePresenceUser,
|
|
8
8
|
PresenceState,
|
|
9
9
|
LivePresence,
|
|
10
|
+
UserMeetingRole,
|
|
10
11
|
} from "@microsoft/live-share";
|
|
11
12
|
import React from "react";
|
|
12
|
-
import { IUseLivePresenceResults } from "../types";
|
|
13
|
+
import { IUseLivePresenceResults, OnUpdateLivePresenceAction } from "../types";
|
|
13
14
|
import { useDynamicDDS } from "../shared-hooks";
|
|
15
|
+
import { useFluidObjectsContext } from "../providers";
|
|
16
|
+
import {
|
|
17
|
+
ActionContainerNotJoinedError,
|
|
18
|
+
ActionLiveDataObjectInitializedError,
|
|
19
|
+
ActionLiveDataObjectUndefinedError,
|
|
20
|
+
} from "../internal";
|
|
14
21
|
|
|
15
22
|
/**
|
|
16
23
|
* React hook for using a Live Share `LivePresence`.
|
|
@@ -21,20 +28,20 @@ import { useDynamicDDS } from "../shared-hooks";
|
|
|
21
28
|
* user data. This is useful for rendering a list of users, profile pictures, cursor positions, and more.
|
|
22
29
|
*
|
|
23
30
|
* @template TData Optional typing for the custom user presence data object. Default is `object` type.
|
|
24
|
-
|
|
31
|
+
* @param uniqueKey The unique key for `LivePresence`. If one does not yet exist, a new one
|
|
25
32
|
* @param userId Optional. The unique ID for a user. If none is provided, a random UUID will be generated.
|
|
26
|
-
* @param initialData Optional. Initial presence data object for the user.
|
|
33
|
+
* @param initialData Optional. Initial presence data object for the user. Can be value or a function to get the value.
|
|
27
34
|
* @param initialPresenceState Optional. Initial status of the user's presence. Default is online.
|
|
28
|
-
* @param
|
|
35
|
+
* @param allowedRoles Optional. the user roles that are allowed to mutate the synchronized state
|
|
29
36
|
* will be created, otherwise it will use the existing one. Default value is ":<dds-default>"
|
|
30
37
|
* @returns stateful `localUser`, `otherUsers` list, and `allUsers` list. Also returns a callback method
|
|
31
38
|
* to update the local user's presence and the `LivePresence` Fluid object.
|
|
32
39
|
*/
|
|
33
40
|
export function useLivePresence<TData extends object = object>(
|
|
34
|
-
|
|
35
|
-
initialData?: TData | undefined,
|
|
41
|
+
uniqueKey: string,
|
|
42
|
+
initialData?: TData | (() => TData) | undefined,
|
|
36
43
|
initialPresenceState: PresenceState = PresenceState.online,
|
|
37
|
-
|
|
44
|
+
allowedRoles?: UserMeetingRole[]
|
|
38
45
|
): IUseLivePresenceResults<TData> {
|
|
39
46
|
/**
|
|
40
47
|
* Stateful all user presence list and its non-user-facing setter method.
|
|
@@ -45,58 +52,60 @@ export function useLivePresence<TData extends object = object>(
|
|
|
45
52
|
/**
|
|
46
53
|
* User facing: dynamically load the DDS for the given unique key.
|
|
47
54
|
*/
|
|
48
|
-
const { dds: livePresence } = useDynamicDDS<LivePresence<TData>>(
|
|
55
|
+
const { dds: livePresence } = useDynamicDDS<LivePresence<TData>>(
|
|
56
|
+
uniqueKey,
|
|
57
|
+
LivePresence<TData>
|
|
58
|
+
);
|
|
49
59
|
|
|
50
60
|
/**
|
|
51
61
|
* User facing: list of non-local user's presence objects.
|
|
52
62
|
*/
|
|
53
|
-
const otherUsers =
|
|
54
|
-
return [...allUsers.filter((user) => !user.isLocalUser)];
|
|
55
|
-
}, [allUsers]);
|
|
63
|
+
const otherUsers = allUsers.filter((user) => !user.isLocalUser);
|
|
56
64
|
|
|
57
65
|
/**
|
|
58
66
|
* User facing: local user's presence object.
|
|
59
67
|
*/
|
|
60
|
-
const localUser =
|
|
61
|
-
|
|
62
|
-
}
|
|
68
|
+
const localUser = allUsers.find((user) => user.isLocalUser);
|
|
69
|
+
|
|
70
|
+
const { container } = useFluidObjectsContext();
|
|
63
71
|
|
|
64
72
|
/**
|
|
65
73
|
* User facing: callback to update the local user's presence.
|
|
66
74
|
*/
|
|
67
|
-
const updatePresence = React.useCallback(
|
|
68
|
-
(
|
|
69
|
-
if (!
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
const updatePresence: OnUpdateLivePresenceAction<TData> = React.useCallback(
|
|
76
|
+
async (data?: TData | undefined, state?: PresenceState | undefined) => {
|
|
77
|
+
if (!container) {
|
|
78
|
+
throw new ActionContainerNotJoinedError(
|
|
79
|
+
"livePresence",
|
|
80
|
+
"updatePresence"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (livePresence === undefined) {
|
|
84
|
+
throw new ActionLiveDataObjectUndefinedError(
|
|
85
|
+
"livePresence",
|
|
86
|
+
"updatePresence"
|
|
74
87
|
);
|
|
75
|
-
return;
|
|
76
88
|
}
|
|
77
89
|
if (!livePresence.isInitialized) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
90
|
+
throw new ActionLiveDataObjectInitializedError(
|
|
91
|
+
"livePresence",
|
|
92
|
+
"updatePresence"
|
|
82
93
|
);
|
|
83
|
-
return;
|
|
84
94
|
}
|
|
85
|
-
livePresence.
|
|
95
|
+
return await livePresence.update(data, state);
|
|
86
96
|
},
|
|
87
|
-
[livePresence]
|
|
97
|
+
[container, livePresence]
|
|
88
98
|
);
|
|
89
99
|
|
|
90
100
|
/**
|
|
91
101
|
* Setup change listeners and start `LivePresence` if needed
|
|
92
102
|
*/
|
|
93
103
|
React.useEffect(() => {
|
|
94
|
-
if (livePresence === undefined)
|
|
95
|
-
return;
|
|
104
|
+
if (livePresence === undefined) return;
|
|
96
105
|
|
|
97
106
|
const onPresenceChanged = () => {
|
|
98
107
|
const updatedLocalUsers: LivePresenceUser<TData>[] = [];
|
|
99
|
-
livePresence?.forEach((user) => {
|
|
108
|
+
livePresence?.getUsers().forEach((user) => {
|
|
100
109
|
updatedLocalUsers.push(user);
|
|
101
110
|
});
|
|
102
111
|
setAllUsers(updatedLocalUsers);
|
|
@@ -104,7 +113,13 @@ export function useLivePresence<TData extends object = object>(
|
|
|
104
113
|
livePresence.on("presenceChanged", onPresenceChanged);
|
|
105
114
|
|
|
106
115
|
if (!livePresence.isInitialized) {
|
|
107
|
-
livePresence.initialize(
|
|
116
|
+
livePresence.initialize(
|
|
117
|
+
isInitialDataCallback<TData>(initialData)
|
|
118
|
+
? initialData()
|
|
119
|
+
: initialData,
|
|
120
|
+
initialPresenceState,
|
|
121
|
+
allowedRoles
|
|
122
|
+
);
|
|
108
123
|
} else {
|
|
109
124
|
onPresenceChanged();
|
|
110
125
|
}
|
|
@@ -122,3 +137,7 @@ export function useLivePresence<TData extends object = object>(
|
|
|
122
137
|
updatePresence,
|
|
123
138
|
};
|
|
124
139
|
}
|
|
140
|
+
|
|
141
|
+
function isInitialDataCallback<TData>(value: any): value is () => TData {
|
|
142
|
+
return typeof value === "function";
|
|
143
|
+
}
|