@noya-app/noya-multiplayer-react 0.1.70 → 0.1.72
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +24 -0
- package/dist/index.bundle.js +46 -20
- package/dist/index.d.mts +84 -55
- package/dist/index.d.ts +84 -55
- package/dist/index.js +518 -273
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +471 -233
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/NoyaStateContext.tsx +156 -105
- package/src/__tests__/noyaApp.test.ts +34 -0
- package/src/__tests__/resourcePayload.test.ts +24 -134
- package/src/components/UserPointersOverlay.tsx +22 -20
- package/src/hooks.ts +22 -14
- package/src/inspector/StateInspector.tsx +318 -255
- package/src/inspector/StateInspectorRow.tsx +3 -1
- package/src/inspector/sections/ServerScriptLogsSection.tsx +128 -0
- package/src/inspector/serialization.ts +4 -2
- package/src/inspector/useStateInspector.tsx +10 -4
- package/src/noyaApp.ts +94 -22
- package/src/singleton.tsx +46 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noya-app/noya-multiplayer-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dev": "npm run build -- --watch"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@noya-app/state-manager": "0.1.
|
|
15
|
+
"@noya-app/state-manager": "0.1.58",
|
|
16
16
|
"@noya-app/emitter": "0.1.0",
|
|
17
17
|
"@noya-app/observable": "0.1.12",
|
|
18
18
|
"@noya-app/task-runner": "0.1.6",
|
package/src/NoyaStateContext.tsx
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { MenuItem } from "@noya-app/noya-designsystem";
|
|
4
4
|
import {
|
|
5
5
|
CreateResourceParametersWithoutAccessibleByFileId,
|
|
6
|
+
DeleteResourceParameters,
|
|
6
7
|
diffResourceMaps,
|
|
7
8
|
Input,
|
|
8
9
|
MediaItem,
|
|
@@ -22,17 +23,20 @@ import {
|
|
|
22
23
|
import { useJsonMemo, useStableCallback } from "@noya-app/react-utils";
|
|
23
24
|
import {
|
|
24
25
|
ActivityEventsManager,
|
|
26
|
+
AssetTranscriptionResult,
|
|
25
27
|
CreateParams,
|
|
26
|
-
|
|
28
|
+
ExtractRequestBody,
|
|
27
29
|
MultiplayerPatchMetadata,
|
|
28
30
|
MultiplayerStateManager,
|
|
29
31
|
NoyaManager,
|
|
30
32
|
PublishCallback,
|
|
31
33
|
ResourceManager,
|
|
32
34
|
SafeEval,
|
|
35
|
+
SharedConnectionDataManager,
|
|
33
36
|
StateManagerOptions,
|
|
34
37
|
Static,
|
|
35
38
|
StreamFilter,
|
|
39
|
+
TranscriptionManager,
|
|
36
40
|
TSchema,
|
|
37
41
|
} from "@noya-app/state-manager";
|
|
38
42
|
import React, {
|
|
@@ -88,70 +92,56 @@ export function resourceToCreateParameters(
|
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
type
|
|
95
|
+
type ResourcePatchRequestBody = ExtractRequestBody<"PATCH /api/resources">;
|
|
96
|
+
|
|
97
|
+
type BuildResourcePatchPayloadParameters = {
|
|
92
98
|
addedResources: ResourceCreate[];
|
|
93
99
|
modifiedResources: ModifiedResource[];
|
|
94
|
-
|
|
95
|
-
resourceMap: ResourceMap;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
type BuildCreateResourcePayloadResult = {
|
|
99
|
-
payload: CreateResourceParametersWithoutAccessibleByFileId[];
|
|
100
|
-
consumedModifiedResourceIds: string[];
|
|
100
|
+
removedResources: Resource[];
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
export function
|
|
103
|
+
export function buildResourcePatchPayload({
|
|
104
104
|
addedResources,
|
|
105
105
|
modifiedResources,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const toCreateParameters = resourceToCreateParameters;
|
|
106
|
+
removedResources,
|
|
107
|
+
}: BuildResourcePatchPayloadParameters): ResourcePatchRequestBody {
|
|
108
|
+
const createEntries = addedResources.map(resourceToCreateParameters);
|
|
110
109
|
|
|
111
|
-
const
|
|
112
|
-
|
|
110
|
+
const dedupedCreateEntries = Array.from(
|
|
111
|
+
new Map(createEntries.map((entry) => [entry.path, entry])).values()
|
|
113
112
|
);
|
|
114
113
|
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
)
|
|
126
|
-
.map((resource) => {
|
|
127
|
-
const previousResource = resourcesById.get(resource.id);
|
|
128
|
-
const path = resource.path ?? previousResource?.path;
|
|
129
|
-
|
|
130
|
-
if (!path) return undefined;
|
|
131
|
-
|
|
132
|
-
const updated = newResourceMap[path];
|
|
114
|
+
const updateEntries =
|
|
115
|
+
modifiedResources.map((resource) => {
|
|
116
|
+
const update: NonNullable<ResourcePatchRequestBody["update"]>[number] = {
|
|
117
|
+
id: resource.id,
|
|
118
|
+
...(resource.path !== undefined ? { path: resource.path } : {}),
|
|
119
|
+
...(resource.assetId !== undefined
|
|
120
|
+
? { assetId: resource.assetId }
|
|
121
|
+
: {}),
|
|
122
|
+
...(resource.asset ? { asset: resource.asset } : {}),
|
|
123
|
+
};
|
|
133
124
|
|
|
134
|
-
|
|
125
|
+
return update;
|
|
126
|
+
}) ?? [];
|
|
135
127
|
|
|
136
|
-
|
|
128
|
+
const deleteEntries: DeleteResourceParameters[] = removedResources.map(
|
|
129
|
+
(resource) => ({ id: resource.id })
|
|
130
|
+
);
|
|
137
131
|
|
|
138
|
-
|
|
139
|
-
})
|
|
140
|
-
.filter(
|
|
141
|
-
(
|
|
142
|
-
resource
|
|
143
|
-
): resource is CreateResourceParametersWithoutAccessibleByFileId =>
|
|
144
|
-
resource !== undefined
|
|
145
|
-
);
|
|
132
|
+
const patch: ResourcePatchRequestBody = {};
|
|
146
133
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
134
|
+
if (dedupedCreateEntries.length) {
|
|
135
|
+
patch.create = dedupedCreateEntries;
|
|
136
|
+
}
|
|
137
|
+
if (updateEntries.length) {
|
|
138
|
+
patch.update = updateEntries;
|
|
139
|
+
}
|
|
140
|
+
if (deleteEntries.length) {
|
|
141
|
+
patch.delete = deleteEntries;
|
|
142
|
+
}
|
|
150
143
|
|
|
151
|
-
return
|
|
152
|
-
payload: Array.from(deduped.values()),
|
|
153
|
-
consumedModifiedResourceIds: [...new Set(handledModifiedResourceIds)],
|
|
154
|
-
};
|
|
144
|
+
return patch;
|
|
155
145
|
}
|
|
156
146
|
|
|
157
147
|
export interface NoyaStateProviderProps<
|
|
@@ -159,8 +149,9 @@ export interface NoyaStateProviderProps<
|
|
|
159
149
|
M extends object,
|
|
160
150
|
E extends object,
|
|
161
151
|
MenuT extends string,
|
|
152
|
+
I extends Record<string, any> = Record<string, unknown>,
|
|
162
153
|
> extends Omit<
|
|
163
|
-
UseNoyaStateOptions<S, M, E, MenuT>,
|
|
154
|
+
UseNoyaStateOptions<S, M, E, MenuT, I>,
|
|
164
155
|
"schema" | "mergeHistoryEntries"
|
|
165
156
|
> {
|
|
166
157
|
children: React.ReactNode;
|
|
@@ -169,7 +160,7 @@ export interface NoyaStateProviderProps<
|
|
|
169
160
|
}
|
|
170
161
|
|
|
171
162
|
export type AnyNoyaStateContextValue = {
|
|
172
|
-
noyaManager: NoyaManager<any, any, any, any>;
|
|
163
|
+
noyaManager: NoyaManager<any, any, any, any, any>;
|
|
173
164
|
theme: AppTheme;
|
|
174
165
|
viewType: AppViewType;
|
|
175
166
|
};
|
|
@@ -202,7 +193,7 @@ export function useAnyNoyaStateContext() {
|
|
|
202
193
|
|
|
203
194
|
export function useAnyNoyaManager() {
|
|
204
195
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
205
|
-
return noyaManager as NoyaManager<any, any, any, any>;
|
|
196
|
+
return noyaManager as NoyaManager<any, any, any, any, any>;
|
|
206
197
|
}
|
|
207
198
|
|
|
208
199
|
export function useColorScheme() {
|
|
@@ -327,24 +318,24 @@ export function usePipelineManager() {
|
|
|
327
318
|
return noyaManager.pipelineManager;
|
|
328
319
|
}
|
|
329
320
|
|
|
330
|
-
export function
|
|
321
|
+
export function useUserManager() {
|
|
331
322
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
332
|
-
return noyaManager.
|
|
323
|
+
return noyaManager.userManager;
|
|
333
324
|
}
|
|
334
325
|
|
|
335
326
|
export function useConnectedUsers() {
|
|
336
|
-
const
|
|
337
|
-
return useObservable(
|
|
327
|
+
const userManager = useUserManager();
|
|
328
|
+
return useObservable(userManager?.connectedUsers$);
|
|
338
329
|
}
|
|
339
330
|
|
|
340
331
|
export function useConnectedUser(userId?: string | null) {
|
|
341
|
-
const
|
|
332
|
+
const userManager = useUserManager();
|
|
342
333
|
return useObservable(
|
|
343
|
-
|
|
334
|
+
userManager?.connectedUsers$,
|
|
344
335
|
useCallback(
|
|
345
336
|
(users) => {
|
|
346
337
|
return users.find((user) => {
|
|
347
|
-
const prefix = user.
|
|
338
|
+
const prefix = user.connectionId.slice(0, 8);
|
|
348
339
|
return userId?.includes(prefix);
|
|
349
340
|
});
|
|
350
341
|
},
|
|
@@ -353,14 +344,47 @@ export function useConnectedUser(userId?: string | null) {
|
|
|
353
344
|
);
|
|
354
345
|
}
|
|
355
346
|
|
|
356
|
-
export function
|
|
347
|
+
export function useAnySharedConnectionData() {
|
|
357
348
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
358
|
-
return noyaManager.
|
|
349
|
+
return noyaManager.sharedConnectionDataManager;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export function useEnqueueInput<
|
|
353
|
+
I extends Record<string, any> = Record<string, unknown>
|
|
354
|
+
>() {
|
|
355
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
356
|
+
return noyaManager.enqueueInput as NoyaManager<
|
|
357
|
+
any,
|
|
358
|
+
any,
|
|
359
|
+
any,
|
|
360
|
+
any,
|
|
361
|
+
I
|
|
362
|
+
>["enqueueInput"];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export function useNoyaUser() {
|
|
366
|
+
const userManager = useUserManager();
|
|
367
|
+
return useObservable(userManager?.currentUser$);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function useNoyaId() {
|
|
371
|
+
const userManager = useUserManager();
|
|
372
|
+
return useObservable(userManager?.currentId$);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function useNoyaUserId() {
|
|
376
|
+
const userManager = useUserManager();
|
|
377
|
+
return useObservable(userManager?.currentUserId$);
|
|
359
378
|
}
|
|
360
379
|
|
|
361
|
-
export function
|
|
362
|
-
const
|
|
363
|
-
return useObservable(
|
|
380
|
+
export function useNoyaConnectionId() {
|
|
381
|
+
const userManager = useUserManager();
|
|
382
|
+
return useObservable(userManager?.currentConnectionId$);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export function useNoyaClientId() {
|
|
386
|
+
const userManager = useUserManager();
|
|
387
|
+
return useObservable(userManager?.currentClientId$);
|
|
364
388
|
}
|
|
365
389
|
|
|
366
390
|
export function useIsProcessing() {
|
|
@@ -389,6 +413,50 @@ export function useResourceManager(): ResourceManager {
|
|
|
389
413
|
return noyaManager.resourceManager;
|
|
390
414
|
}
|
|
391
415
|
|
|
416
|
+
export function useNoyaTranscriptionManager(): TranscriptionManager {
|
|
417
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
418
|
+
return noyaManager.transcriptionManager;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
type UseNoyaAssetTranscriptionOptions = {
|
|
422
|
+
endpoint?: string;
|
|
423
|
+
apiKey?: string;
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Returns a text transcription for the given assetId.
|
|
428
|
+
*
|
|
429
|
+
* - This API is available when running your app on noya.io, not when running it locally.
|
|
430
|
+
* - An asset must first be uploaded via the `useAssetManager().create()` method before
|
|
431
|
+
* it can be transcribed via this API.
|
|
432
|
+
* - The asset must be a valid audio or video file.
|
|
433
|
+
*/
|
|
434
|
+
export function useNoyaAssetTranscription(
|
|
435
|
+
assetId: string,
|
|
436
|
+
options?: UseNoyaAssetTranscriptionOptions
|
|
437
|
+
): AssetTranscriptionResult;
|
|
438
|
+
export function useNoyaAssetTranscription(
|
|
439
|
+
assetId?: string,
|
|
440
|
+
options?: UseNoyaAssetTranscriptionOptions
|
|
441
|
+
): AssetTranscriptionResult | undefined;
|
|
442
|
+
export function useNoyaAssetTranscription(
|
|
443
|
+
assetId?: string,
|
|
444
|
+
options?: UseNoyaAssetTranscriptionOptions
|
|
445
|
+
): AssetTranscriptionResult | undefined {
|
|
446
|
+
const transcriptionManager = useNoyaTranscriptionManager();
|
|
447
|
+
|
|
448
|
+
const observable = useMemo(() => {
|
|
449
|
+
if (!assetId) return undefined;
|
|
450
|
+
|
|
451
|
+
return transcriptionManager.getAssetTranscription$(assetId, {
|
|
452
|
+
endpoint: options?.endpoint,
|
|
453
|
+
apiKey: options?.apiKey,
|
|
454
|
+
});
|
|
455
|
+
}, [transcriptionManager, assetId, options?.endpoint, options?.apiKey]);
|
|
456
|
+
|
|
457
|
+
return useObservable(observable);
|
|
458
|
+
}
|
|
459
|
+
|
|
392
460
|
// export function useResources(): Resource[] {
|
|
393
461
|
// const { noyaManager } = useAnyNoyaStateContext();
|
|
394
462
|
// const resources = useObservable(noyaManager.resourceManager.resources$);
|
|
@@ -431,29 +499,20 @@ export function useResources({
|
|
|
431
499
|
const { addedResources, removedResources, modifiedResources } =
|
|
432
500
|
diffResourceMaps(resourceMap, newResourceMap, "id");
|
|
433
501
|
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
resourceMap,
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
if (createPayload.length > 0) {
|
|
443
|
-
await resourceManager.createResource(createPayload);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const consumedModifiedResourceIdsSet = new Set(
|
|
447
|
-
consumedModifiedResourceIds
|
|
448
|
-
);
|
|
502
|
+
const patchPayload = buildResourcePatchPayload({
|
|
503
|
+
addedResources,
|
|
504
|
+
modifiedResources,
|
|
505
|
+
removedResources,
|
|
506
|
+
});
|
|
449
507
|
|
|
450
|
-
const
|
|
451
|
-
(
|
|
452
|
-
|
|
508
|
+
const hasPatchOperations =
|
|
509
|
+
(patchPayload.create?.length ?? 0) > 0 ||
|
|
510
|
+
(patchPayload.update?.length ?? 0) > 0 ||
|
|
511
|
+
(patchPayload.delete?.length ?? 0) > 0;
|
|
453
512
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
513
|
+
if (hasPatchOperations) {
|
|
514
|
+
await resourceManager.patchResources(patchPayload);
|
|
515
|
+
}
|
|
457
516
|
|
|
458
517
|
if (shouldDeleteAssets) {
|
|
459
518
|
for (const resource of removedResources) {
|
|
@@ -462,17 +521,6 @@ export function useResources({
|
|
|
462
521
|
}
|
|
463
522
|
}
|
|
464
523
|
}
|
|
465
|
-
|
|
466
|
-
await Promise.all(
|
|
467
|
-
remainingModifiedResources.map(({ id, path, assetId, asset }) =>
|
|
468
|
-
resourceManager.updateResource({
|
|
469
|
-
id,
|
|
470
|
-
path,
|
|
471
|
-
assetId,
|
|
472
|
-
...(assetId ? {} : asset ? { asset } : {}),
|
|
473
|
-
})
|
|
474
|
-
)
|
|
475
|
-
);
|
|
476
524
|
},
|
|
477
525
|
[resourceMap, resourceManager, shouldDeleteAssets, assetManager]
|
|
478
526
|
);
|
|
@@ -535,6 +583,7 @@ export function createNoyaContext<
|
|
|
535
583
|
M extends object = object,
|
|
536
584
|
E extends object = object,
|
|
537
585
|
MenuT extends string = string,
|
|
586
|
+
I extends Record<string, any> = Record<string, unknown>,
|
|
538
587
|
>({
|
|
539
588
|
schema,
|
|
540
589
|
mergeHistoryEntries,
|
|
@@ -557,7 +606,7 @@ export function createNoyaContext<
|
|
|
557
606
|
>;
|
|
558
607
|
|
|
559
608
|
const NoyaStateContext = AnyNoyaStateContext as React.Context<
|
|
560
|
-
NoyaManager<S, M, E> | undefined
|
|
609
|
+
NoyaManager<S, M, E, MenuT, I> | undefined
|
|
561
610
|
>;
|
|
562
611
|
|
|
563
612
|
function NoyaContextProvider({
|
|
@@ -578,12 +627,13 @@ export function createNoyaContext<
|
|
|
578
627
|
children,
|
|
579
628
|
initialState,
|
|
580
629
|
...options
|
|
581
|
-
}: NoyaStateProviderProps<S, M, E, MenuT>) {
|
|
630
|
+
}: NoyaStateProviderProps<S, M, E, MenuT, I>) {
|
|
582
631
|
const [, , { noyaManager, theme, viewType }] = useNoyaStateInternal<
|
|
583
632
|
S,
|
|
584
633
|
M,
|
|
585
634
|
E,
|
|
586
|
-
MenuT
|
|
635
|
+
MenuT,
|
|
636
|
+
I
|
|
587
637
|
>(initialState, {
|
|
588
638
|
schema,
|
|
589
639
|
mergeHistoryEntries,
|
|
@@ -730,9 +780,9 @@ export function createNoyaContext<
|
|
|
730
780
|
>;
|
|
731
781
|
}
|
|
732
782
|
|
|
733
|
-
function
|
|
783
|
+
function useSharedConnectionDataManager() {
|
|
734
784
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
735
|
-
return noyaManager.
|
|
785
|
+
return noyaManager.sharedConnectionDataManager as SharedConnectionDataManager<E>;
|
|
736
786
|
}
|
|
737
787
|
|
|
738
788
|
function useNoyaManager() {
|
|
@@ -740,7 +790,8 @@ export function createNoyaContext<
|
|
|
740
790
|
S,
|
|
741
791
|
PartialM,
|
|
742
792
|
E,
|
|
743
|
-
MenuT
|
|
793
|
+
MenuT,
|
|
794
|
+
I
|
|
744
795
|
>;
|
|
745
796
|
}
|
|
746
797
|
|
|
@@ -812,7 +863,7 @@ export function createNoyaContext<
|
|
|
812
863
|
useSetValue,
|
|
813
864
|
useValueState,
|
|
814
865
|
useStateManager,
|
|
815
|
-
|
|
866
|
+
useSharedConnectionDataManager,
|
|
816
867
|
useLeftMenuItems,
|
|
817
868
|
useSetLeftMenuItems,
|
|
818
869
|
useRightMenuItems,
|
|
@@ -13,6 +13,8 @@ it("gets AppData with no data", () => {
|
|
|
13
13
|
viewType: "editable",
|
|
14
14
|
initialState,
|
|
15
15
|
inspector: false,
|
|
16
|
+
isDemo: false,
|
|
17
|
+
access: "write",
|
|
16
18
|
});
|
|
17
19
|
});
|
|
18
20
|
|
|
@@ -37,6 +39,8 @@ it("gets AppData with data param", () => {
|
|
|
37
39
|
viewType: "editable",
|
|
38
40
|
initialState: { foo: "bar" },
|
|
39
41
|
inspector: false,
|
|
42
|
+
isDemo: false,
|
|
43
|
+
access: "write",
|
|
40
44
|
});
|
|
41
45
|
});
|
|
42
46
|
|
|
@@ -50,6 +54,8 @@ it("uses initial state if data doesn't parse", () => {
|
|
|
50
54
|
viewType: "editable",
|
|
51
55
|
initialState: { foo: "bar" },
|
|
52
56
|
inspector: false,
|
|
57
|
+
isDemo: false,
|
|
58
|
+
access: "write",
|
|
53
59
|
});
|
|
54
60
|
});
|
|
55
61
|
|
|
@@ -67,9 +73,33 @@ it("gets AppData with schema", () => {
|
|
|
67
73
|
viewType: "editable",
|
|
68
74
|
initialState: { foo: "bar" },
|
|
69
75
|
inspector: false,
|
|
76
|
+
isDemo: false,
|
|
77
|
+
access: "write",
|
|
70
78
|
});
|
|
71
79
|
});
|
|
72
80
|
|
|
81
|
+
it("preserves userId from data param", () => {
|
|
82
|
+
const existing = {
|
|
83
|
+
theme: "light",
|
|
84
|
+
viewType: "editable",
|
|
85
|
+
initialState: { foo: "bar" },
|
|
86
|
+
inspector: false,
|
|
87
|
+
userId: "user-123",
|
|
88
|
+
isDemo: true,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const data = getAppData(null as unknown, undefined, {
|
|
92
|
+
window: {
|
|
93
|
+
location: {
|
|
94
|
+
hash: `#data=${encodeURIComponent(JSON.stringify(existing))}`,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(data.userId).toBe("user-123");
|
|
100
|
+
expect(data.isDemo).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
|
|
73
103
|
// it("enforces schema on data param", () => {
|
|
74
104
|
// const schema = Type.Object({
|
|
75
105
|
// foo: Type.String({ default: "bar" }),
|
|
@@ -103,6 +133,8 @@ it("gets AppData with function initial state", () => {
|
|
|
103
133
|
viewType: "editable",
|
|
104
134
|
initialState: { foo: "bar" },
|
|
105
135
|
inspector: false,
|
|
136
|
+
isDemo: false,
|
|
137
|
+
access: "write",
|
|
106
138
|
});
|
|
107
139
|
});
|
|
108
140
|
|
|
@@ -130,6 +162,8 @@ it("even if initial state does not match schema, make sure we use multiplayer ur
|
|
|
130
162
|
initialState: { foo: "" },
|
|
131
163
|
inspector: false,
|
|
132
164
|
multiplayerUrl: "https://example.com",
|
|
165
|
+
isDemo: false,
|
|
166
|
+
access: "write",
|
|
133
167
|
});
|
|
134
168
|
});
|
|
135
169
|
|